Shard refs/draft-comments/* by change instead of account ID

The motivation is the same as in Ib81d462: scanning the whole
refs/draft-comments/* space (with grows without bound) when reindexing
a change is potentially too slow.

Instead of refs/draft-comments/<sharded account>/<change>, use
refs/draft-comments/<sharded change>/<account>. This is mostly
straightforward, since there are relatively few places that scan
multiple refs; most callers just use the helper method in RefNames.

Change-Id: I063e2c496751f637d968c89c1501743074fb9025
This commit is contained in:
Dave Borowitz
2016-05-02 17:44:07 -04:00
committed by Edwin Kempin
parent dba0801601
commit 66c76c9d4a
13 changed files with 114 additions and 66 deletions

View File

@@ -125,6 +125,21 @@ public final class Account {
Integer id = RefNames.parseShardedRefPart(name);
return id != null ? new Account.Id(id) : null;
}
/**
* Parse an Account.Id out of the last part of a ref name.
* <p>
* The input is a ref name of the form {@code ".../1234"}, where the suffix
* is a non-sharded account ID. Ref names using a sharded ID should use
* {@link #fromRefPart(String)} instead for greater safety.
*
* @param name ref name
* @return account ID, or null if not numeric.
*/
public static Id fromRefSuffix(String name) {
Integer id = RefNames.parseRefSuffix(name);
return id != null ? new Account.Id(id) : null;
}
}
@Column(id = 1)

View File

@@ -163,6 +163,11 @@ public final class Change {
return new Change.Id(Integer.parseInt(id));
}
public static Id fromRefPart(String ref) {
Integer id = RefNames.parseShardedRefPart(ref);
return id != null ? new Change.Id(id) : null;
}
static int startIndex(String ref) {
if (ref == null || !ref.startsWith(REFS_CHANGES)) {
return -1;

View File

@@ -107,15 +107,15 @@ public class RefNames {
return r.toString();
}
public static String refsDraftComments(Account.Id accountId,
Change.Id changeId) {
StringBuilder r = buildRefsPrefix(REFS_DRAFT_COMMENTS, accountId.get());
r.append(changeId.get());
public static String refsDraftComments(Change.Id changeId,
Account.Id accountId) {
StringBuilder r = buildRefsPrefix(REFS_DRAFT_COMMENTS, changeId.get());
r.append(accountId.get());
return r.toString();
}
public static String refsDraftCommentsPrefix(Account.Id accountId) {
return buildRefsPrefix(REFS_DRAFT_COMMENTS, accountId.get()).toString();
public static String refsDraftCommentsPrefix(Change.Id changeId) {
return buildRefsPrefix(REFS_DRAFT_COMMENTS, changeId.get()).toString();
}
public static String refsStarredChanges(Change.Id changeId,
@@ -217,6 +217,26 @@ public class RefNames {
return id;
}
static Integer parseRefSuffix(String name) {
if (name == null) {
return null;
}
int i = name.length();
while (i > 0) {
char c = name.charAt(i - 1);
if (c == '/') {
break;
} else if (!Character.isDigit(c)) {
return null;
}
i--;
}
if (i == 0) {
return null;
}
return Integer.valueOf(name.substring(i, name.length()));
}
private RefNames() {
}
}

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.reviewdb.client;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.reviewdb.client.Account.Id.fromRef;
import static com.google.gerrit.reviewdb.client.Account.Id.fromRefPart;
import static com.google.gerrit.reviewdb.client.Account.Id.fromRefSuffix;
import org.junit.Test;
@@ -48,6 +49,12 @@ public class AccountTest {
assertThat(fromRefPart("ab/cd")).isNull();
}
@Test
public void parseRefSuffix() {
assertThat(fromRefSuffix("12/34")).isEqualTo(id(34));
assertThat(fromRefSuffix("ab/cd")).isNull();
}
private Account.Id id(int n) {
return new Account.Id(n);
}

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.reviewdb.client;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.reviewdb.client.RefNames.parseShardedRefPart;
import static com.google.gerrit.reviewdb.client.RefNames.parseRefSuffix;
import org.junit.Test;
@@ -39,14 +40,14 @@ public class RefNamesTest {
@Test
public void refsDraftComments() throws Exception {
assertThat(RefNames.refsDraftComments(accountId, changeId))
.isEqualTo("refs/draft-comments/23/1011123/67473");
assertThat(RefNames.refsDraftComments(changeId, accountId))
.isEqualTo("refs/draft-comments/73/67473/1011123");
}
@Test
public void refsDraftCommentsPrefix() throws Exception {
assertThat(RefNames.refsDraftCommentsPrefix(accountId))
.isEqualTo("refs/draft-comments/23/1011123/");
assertThat(RefNames.refsDraftCommentsPrefix(changeId))
.isEqualTo("refs/draft-comments/73/67473/");
}
@Test
@@ -89,4 +90,19 @@ public class RefNamesTest {
// Shard too short.
assertThat(parseShardedRefPart("1/1")).isNull();
}
@Test
public void testParseRefSuffix() throws Exception {
assertThat(parseRefSuffix("1/2/34")).isEqualTo(34);
assertThat(parseRefSuffix("/34")).isEqualTo(34);
assertThat(parseRefSuffix(null)).isNull();
assertThat(parseRefSuffix("")).isNull();
assertThat(parseRefSuffix("34")).isNull();
assertThat(parseRefSuffix("12/ab")).isNull();
assertThat(parseRefSuffix("12/a4")).isNull();
assertThat(parseRefSuffix("12/4a")).isNull();
assertThat(parseRefSuffix("a4")).isNull();
assertThat(parseRefSuffix("4a")).isNull();
}
}