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:
		
				
					committed by
					
						
						Edwin Kempin
					
				
			
			
				
	
			
			
			
						parent
						
							dba0801601
						
					
				
				
					commit
					66c76c9d4a
				
			@@ -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)
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user