Make new message UUIDs more URL encoding friendly

=, + and / require triplet encoding in URLs. Cleanup the base64
encoding string to use different characters. This only impacts
newly created string, existing strings will continue to require a
much longer encoding when sent in JSON messages from the REST API.

Also strip leading 'A'. Most strings start with a run of 'A' due
to the first few bytes of uuidPrefix always being 0.

Avoid long runs of - in the resulting IDs by mixing the bits using
the uuidPrefix as the salt for the mixer.

Change-Id: I0a7da0aec071329c840447a0914d14118f2f20a4
This commit is contained in:
Shawn O. Pearce
2012-11-23 22:27:20 -08:00
parent 04a17cfa75
commit d2cdaa609d
2 changed files with 11 additions and 5 deletions

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server; package com.google.gerrit.server;
import com.google.common.base.CharMatcher;
import com.google.gerrit.common.ChangeHooks; import com.google.gerrit.common.ChangeHooks;
import com.google.gerrit.reviewdb.client.Change; import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage; import com.google.gerrit.reviewdb.client.ChangeMessage;
@@ -35,6 +36,7 @@ import com.google.gerrit.server.patch.PatchSetInfoFactory;
import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException; import com.google.gerrit.server.patch.PatchSetInfoNotAvailableException;
import com.google.gerrit.server.project.InvalidChangeOperationException; import com.google.gerrit.server.project.InvalidChangeOperationException;
import com.google.gerrit.server.project.NoSuchChangeException; import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.util.IdGenerator;
import com.google.gwtorm.server.AtomicUpdate; import com.google.gwtorm.server.AtomicUpdate;
import com.google.gwtorm.server.OrmConcurrencyException; import com.google.gwtorm.server.OrmConcurrencyException;
import com.google.gwtorm.server.OrmException; import com.google.gwtorm.server.OrmException;
@@ -66,7 +68,6 @@ import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
public class ChangeUtil { public class ChangeUtil {
private static final Logger log = LoggerFactory.getLogger(ChangeUtil.class); private static final Logger log = LoggerFactory.getLogger(ChangeUtil.class);
private static int uuidPrefix; private static int uuidPrefix;
@@ -83,7 +84,12 @@ public class ChangeUtil {
public static String messageUUID(final ReviewDb db) throws OrmException { public static String messageUUID(final ReviewDb db) throws OrmException {
final byte[] raw = new byte[8]; final byte[] raw = new byte[8];
fill(raw, db); fill(raw, db);
return Base64.encodeBytes(raw);
// Make the resulting base64 string more URL friendly.
return CharMatcher.is('A').trimLeadingFrom(
CharMatcher.is('=').trimTrailingFrom(Base64.encodeBytes(raw)))
.replace('+', '.')
.replace('/', '-');
} }
private static synchronized void fill(byte[] raw, ReviewDb db) private static synchronized void fill(byte[] raw, ReviewDb db)
@@ -93,7 +99,7 @@ public class ChangeUtil {
uuidSeq = Integer.MAX_VALUE; uuidSeq = Integer.MAX_VALUE;
} }
NB.encodeInt32(raw, 0, uuidPrefix); NB.encodeInt32(raw, 0, uuidPrefix);
NB.encodeInt32(raw, 4, uuidSeq--); NB.encodeInt32(raw, 4, IdGenerator.mix(uuidPrefix, uuidSeq--));
} }
public static void touch(final Change change, ReviewDb db) public static void touch(final Change change, ReviewDb db)

View File

@@ -43,13 +43,13 @@ public class IdGenerator {
/** Produce the next identifier. */ /** Produce the next identifier. */
public int next() { public int next() {
return mix(gen.getAndIncrement()); return mix(salt, gen.getAndIncrement());
} }
private static final int salt = 0x9e3779b9; private static final int salt = 0x9e3779b9;
/** A very simple bit permutation to mask a simple incrementer. */ /** A very simple bit permutation to mask a simple incrementer. */
static int mix(final int in) { public static int mix(final int salt, final int in) {
short v0 = hi16(in); short v0 = hi16(in);
short v1 = lo16(in); short v1 = lo16(in);
v0 += ((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1; v0 += ((v1 << 2) + 0 ^ v1) + (salt ^ (v1 >>> 3)) + 1;