ScanningChangeCacheImpl: Load changes from notedb if enabled

ScanningChangeCacheImpl now loads the changes via ChangeNotes.Factory
from notedb if reading from notedb is enabled. If the changes need to
be read from database ChangeNotes.Factory is not used since the
changes should be loaded in a batch and ChangeNotes.Factory doesn't
support this.

Change-Id: I44947eb36ec5bbf07d60beabf154dbaadf0918c2
Signed-off-by: Edwin Kempin <ekempin@google.com>
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/ScanningChangeCacheImpl.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/ScanningChangeCacheImpl.java
index faf3776..bf04e21 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/git/ScanningChangeCacheImpl.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/ScanningChangeCacheImpl.java
@@ -24,6 +24,8 @@
 import com.google.gerrit.reviewdb.client.RefNames;
 import com.google.gerrit.reviewdb.server.ReviewDb;
 import com.google.gerrit.server.cache.CacheModule;
+import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.notedb.NotesMigration;
 import com.google.gerrit.server.util.ManualRequestContext;
 import com.google.gerrit.server.util.OneOffRequestContext;
 import com.google.gwtorm.server.OrmException;
@@ -86,12 +88,18 @@
 
   static class Loader extends CacheLoader<Project.NameKey, List<Change>> {
     private final GitRepositoryManager repoManager;
+    private final NotesMigration notesMigration;
+    private final ChangeNotes.Factory notesFactory;
     private final OneOffRequestContext requestContext;
 
     @Inject
     Loader(GitRepositoryManager repoManager,
+        NotesMigration notesMigration,
+        ChangeNotes.Factory notesFactory,
         OneOffRequestContext requestContext) {
       this.repoManager = repoManager;
+      this.notesMigration = notesMigration;
+      this.notesFactory = notesFactory;
       this.requestContext = requestContext;
     }
 
@@ -99,13 +107,23 @@
     public List<Change> load(Project.NameKey key) throws Exception {
       try (Repository repo = repoManager.openRepository(key);
           ManualRequestContext ctx = requestContext.open()) {
-        return scan(repo, ctx.getReviewDbProvider().get());
+        return scan(notesMigration, notesFactory, repo,
+            ctx.getReviewDbProvider().get(), key);
       }
     }
-
   }
 
-  public static List<Change> scan(Repository repo, ReviewDb db)
+  public static List<Change> scan(NotesMigration notesMigration,
+      ChangeNotes.Factory notesFactory, Repository repo, ReviewDb db,
+      Project.NameKey project) throws OrmException, IOException {
+    if (!notesMigration.readChanges()) {
+      return scanDb(repo, db);
+    }
+
+    return scanNotedb(notesFactory, repo, db, project);
+  }
+
+  public static List<Change> scanDb(Repository repo, ReviewDb db)
       throws OrmException, IOException {
     Map<String, Ref> refs =
         repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES);
@@ -124,4 +142,19 @@
     }
     return changes;
   }
+
+  public static List<Change> scanNotedb(ChangeNotes.Factory notesFactory,
+      Repository repo, ReviewDb db, Project.NameKey project)
+          throws OrmException, IOException {
+    Map<String, Ref> refs =
+        repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES);
+    List<Change> changes = new ArrayList<>(refs.size());
+    for (Ref r : refs.values()) {
+      Change.Id id = Change.Id.fromRef(r.getName());
+      if (id != null) {
+        changes.add(notesFactory.create(db, project, id).getChange());
+      }
+    }
+    return changes;
+  }
 }
diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java b/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java
index 53af8ad..11bbbd8 100644
--- a/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java
+++ b/gerrit-server/src/main/java/com/google/gerrit/server/index/SiteIndexer.java
@@ -37,6 +37,8 @@
 import com.google.gerrit.server.git.MergeUtil;
 import com.google.gerrit.server.git.MultiProgressMonitor;
 import com.google.gerrit.server.git.MultiProgressMonitor.Task;
+import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.notedb.NotesMigration;
 import com.google.gerrit.server.git.ScanningChangeCacheImpl;
 import com.google.gerrit.server.patch.PatchListLoader;
 import com.google.gerrit.server.query.change.ChangeData;
@@ -116,6 +118,8 @@
   private final GitRepositoryManager repoManager;
   private final ListeningExecutorService executor;
   private final ChangeIndexer.Factory indexerFactory;
+  private final NotesMigration notesMigration;
+  private final ChangeNotes.Factory notesFactory;
   private final ThreeWayMergeStrategy mergeStrategy;
 
   private int numChanges = -1;
@@ -129,12 +133,16 @@
       GitRepositoryManager repoManager,
       @IndexExecutor(BATCH) ListeningExecutorService executor,
       ChangeIndexer.Factory indexerFactory,
+      NotesMigration notesMigration,
+      ChangeNotes.Factory notesFactory,
       @GerritServerConfig Config config) {
     this.schemaFactory = schemaFactory;
     this.changeDataFactory = changeDataFactory;
     this.repoManager = repoManager;
     this.executor = executor;
     this.indexerFactory = indexerFactory;
+    this.notesMigration = notesMigration;
+    this.notesFactory = notesFactory;
     this.mergeStrategy = MergeUtil.getMergeStrategy(config);
   }
 
@@ -238,7 +246,8 @@
         try (Repository repo = repoManager.openRepository(project);
             ReviewDb db = schemaFactory.open()) {
           Map<String, Ref> refs = repo.getRefDatabase().getRefs(ALL);
-          for (Change c : ScanningChangeCacheImpl.scan(repo, db)) {
+          for (Change c : ScanningChangeCacheImpl.scan(notesMigration,
+              notesFactory, repo, db, project)) {
             Ref r = refs.get(c.currentPatchSetId().toRefName());
             if (r != null) {
               byId.put(r.getObjectId(), changeDataFactory.create(db, c));