Move methods for scanning change refs into ChangeNotes.Factory
All remaining code that loads changes in batches from the database should go into ChangeNotes.Factory. Change-Id: Ib1d8c09f78e3f6d898378e91b501fa4d1ec154d5 Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
@@ -19,36 +19,25 @@ import static com.google.gerrit.server.git.SearchingChangeCacheImpl.ID_CACHE;
|
|||||||
import com.google.common.base.Function;
|
import com.google.common.base.Function;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import com.google.common.collect.Iterables;
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
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.cache.CacheModule;
|
||||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
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.ManualRequestContext;
|
||||||
import com.google.gerrit.server.util.OneOffRequestContext;
|
import com.google.gerrit.server.util.OneOffRequestContext;
|
||||||
import com.google.gwtorm.server.OrmException;
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Module;
|
import com.google.inject.Module;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
import com.google.inject.name.Named;
|
import com.google.inject.name.Named;
|
||||||
|
|
||||||
import org.eclipse.jgit.lib.Ref;
|
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -90,17 +79,14 @@ public class ScanningChangeCacheImpl implements ChangeCache {
|
|||||||
|
|
||||||
static class Loader extends CacheLoader<Project.NameKey, List<Change>> {
|
static class Loader extends CacheLoader<Project.NameKey, List<Change>> {
|
||||||
private final GitRepositoryManager repoManager;
|
private final GitRepositoryManager repoManager;
|
||||||
private final NotesMigration notesMigration;
|
|
||||||
private final ChangeNotes.Factory notesFactory;
|
private final ChangeNotes.Factory notesFactory;
|
||||||
private final OneOffRequestContext requestContext;
|
private final OneOffRequestContext requestContext;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
Loader(GitRepositoryManager repoManager,
|
Loader(GitRepositoryManager repoManager,
|
||||||
NotesMigration notesMigration,
|
|
||||||
ChangeNotes.Factory notesFactory,
|
ChangeNotes.Factory notesFactory,
|
||||||
OneOffRequestContext requestContext) {
|
OneOffRequestContext requestContext) {
|
||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.notesMigration = notesMigration;
|
|
||||||
this.notesFactory = notesFactory;
|
this.notesFactory = notesFactory;
|
||||||
this.requestContext = requestContext;
|
this.requestContext = requestContext;
|
||||||
}
|
}
|
||||||
@@ -109,66 +95,15 @@ public class ScanningChangeCacheImpl implements ChangeCache {
|
|||||||
public List<Change> load(Project.NameKey key) throws Exception {
|
public List<Change> load(Project.NameKey key) throws Exception {
|
||||||
try (Repository repo = repoManager.openRepository(key);
|
try (Repository repo = repoManager.openRepository(key);
|
||||||
ManualRequestContext ctx = requestContext.open()) {
|
ManualRequestContext ctx = requestContext.open()) {
|
||||||
return scan(notesMigration, notesFactory, repo,
|
return Lists.transform(
|
||||||
ctx.getReviewDbProvider().get(), key);
|
notesFactory.scan(repo, ctx.getReviewDbProvider().get(), key),
|
||||||
|
new Function<ChangeNotes, Change>() {
|
||||||
|
@Override
|
||||||
|
public Change apply(ChangeNotes notes) {
|
||||||
|
return notes.getChange();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 scanChangesFromNotedb(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);
|
|
||||||
Set<Change.Id> ids = new LinkedHashSet<>();
|
|
||||||
for (Ref r : refs.values()) {
|
|
||||||
Change.Id id = Change.Id.fromRef(r.getName());
|
|
||||||
if (id != null) {
|
|
||||||
ids.add(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
List<Change> changes = new ArrayList<>(ids.size());
|
|
||||||
// A batch size of N may overload get(Iterable), so use something smaller,
|
|
||||||
// but still >1.
|
|
||||||
for (List<Change.Id> batch : Iterables.partition(ids, 30)) {
|
|
||||||
Iterables.addAll(changes, db.changes().get(batch));
|
|
||||||
}
|
|
||||||
return changes;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static List<Change> scanChangesFromNotedb(
|
|
||||||
ChangeNotes.Factory notesFactory, Repository repo, ReviewDb db,
|
|
||||||
Project.NameKey project) throws OrmException, IOException {
|
|
||||||
List<ChangeNotes> changeNotes = scanNotedb(notesFactory, repo, db, project);
|
|
||||||
return Lists.transform(changeNotes, new Function<ChangeNotes, Change>() {
|
|
||||||
@Override
|
|
||||||
public Change apply(ChangeNotes notes) {
|
|
||||||
return notes.getChange();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<ChangeNotes> 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<ChangeNotes> changeNotes = new ArrayList<>(refs.size());
|
|
||||||
for (Ref r : refs.values()) {
|
|
||||||
Change.Id id = Change.Id.fromRef(r.getName());
|
|
||||||
if (id != null) {
|
|
||||||
changeNotes.add(notesFactory.create(db, project, id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return changeNotes;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,9 +37,7 @@ import com.google.gerrit.server.git.GitRepositoryManager;
|
|||||||
import com.google.gerrit.server.git.MergeUtil;
|
import com.google.gerrit.server.git.MergeUtil;
|
||||||
import com.google.gerrit.server.git.MultiProgressMonitor;
|
import com.google.gerrit.server.git.MultiProgressMonitor;
|
||||||
import com.google.gerrit.server.git.MultiProgressMonitor.Task;
|
import com.google.gerrit.server.git.MultiProgressMonitor.Task;
|
||||||
import com.google.gerrit.server.git.ScanningChangeCacheImpl;
|
|
||||||
import com.google.gerrit.server.notedb.ChangeNotes;
|
import com.google.gerrit.server.notedb.ChangeNotes;
|
||||||
import com.google.gerrit.server.notedb.NotesMigration;
|
|
||||||
import com.google.gerrit.server.patch.PatchListLoader;
|
import com.google.gerrit.server.patch.PatchListLoader;
|
||||||
import com.google.gerrit.server.query.change.ChangeData;
|
import com.google.gerrit.server.query.change.ChangeData;
|
||||||
import com.google.gwtorm.server.SchemaFactory;
|
import com.google.gwtorm.server.SchemaFactory;
|
||||||
@@ -118,7 +116,6 @@ public class SiteIndexer {
|
|||||||
private final GitRepositoryManager repoManager;
|
private final GitRepositoryManager repoManager;
|
||||||
private final ListeningExecutorService executor;
|
private final ListeningExecutorService executor;
|
||||||
private final ChangeIndexer.Factory indexerFactory;
|
private final ChangeIndexer.Factory indexerFactory;
|
||||||
private final NotesMigration notesMigration;
|
|
||||||
private final ChangeNotes.Factory notesFactory;
|
private final ChangeNotes.Factory notesFactory;
|
||||||
private final ThreeWayMergeStrategy mergeStrategy;
|
private final ThreeWayMergeStrategy mergeStrategy;
|
||||||
|
|
||||||
@@ -133,7 +130,6 @@ public class SiteIndexer {
|
|||||||
GitRepositoryManager repoManager,
|
GitRepositoryManager repoManager,
|
||||||
@IndexExecutor(BATCH) ListeningExecutorService executor,
|
@IndexExecutor(BATCH) ListeningExecutorService executor,
|
||||||
ChangeIndexer.Factory indexerFactory,
|
ChangeIndexer.Factory indexerFactory,
|
||||||
NotesMigration notesMigration,
|
|
||||||
ChangeNotes.Factory notesFactory,
|
ChangeNotes.Factory notesFactory,
|
||||||
@GerritServerConfig Config config) {
|
@GerritServerConfig Config config) {
|
||||||
this.schemaFactory = schemaFactory;
|
this.schemaFactory = schemaFactory;
|
||||||
@@ -141,7 +137,6 @@ public class SiteIndexer {
|
|||||||
this.repoManager = repoManager;
|
this.repoManager = repoManager;
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.indexerFactory = indexerFactory;
|
this.indexerFactory = indexerFactory;
|
||||||
this.notesMigration = notesMigration;
|
|
||||||
this.notesFactory = notesFactory;
|
this.notesFactory = notesFactory;
|
||||||
this.mergeStrategy = MergeUtil.getMergeStrategy(config);
|
this.mergeStrategy = MergeUtil.getMergeStrategy(config);
|
||||||
}
|
}
|
||||||
@@ -257,8 +252,8 @@ public class SiteIndexer {
|
|||||||
try (Repository repo = repoManager.openRepository(project);
|
try (Repository repo = repoManager.openRepository(project);
|
||||||
ReviewDb db = schemaFactory.open()) {
|
ReviewDb db = schemaFactory.open()) {
|
||||||
Map<String, Ref> refs = repo.getRefDatabase().getRefs(ALL);
|
Map<String, Ref> refs = repo.getRefDatabase().getRefs(ALL);
|
||||||
for (Change c : ScanningChangeCacheImpl.scan(notesMigration,
|
for (ChangeNotes cn : notesFactory.scan(repo, db, project)) {
|
||||||
notesFactory, repo, db, project)) {
|
Change c = cn.getChange();
|
||||||
Ref r = refs.get(c.currentPatchSetId().toRefName());
|
Ref r = refs.get(c.currentPatchSetId().toRefName());
|
||||||
if (r != null) {
|
if (r != null) {
|
||||||
byId.put(r.getObjectId(), changeDataFactory.create(db, c));
|
byId.put(r.getObjectId(), changeDataFactory.create(db, c));
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import com.google.common.collect.ImmutableSet;
|
|||||||
import com.google.common.collect.ImmutableSetMultimap;
|
import com.google.common.collect.ImmutableSetMultimap;
|
||||||
import com.google.common.collect.ImmutableSortedMap;
|
import com.google.common.collect.ImmutableSortedMap;
|
||||||
import com.google.common.collect.ImmutableSortedSet;
|
import com.google.common.collect.ImmutableSortedSet;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.ListMultimap;
|
import com.google.common.collect.ListMultimap;
|
||||||
import com.google.common.collect.Ordering;
|
import com.google.common.collect.Ordering;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.primitives.Ints;
|
||||||
@@ -43,12 +44,12 @@ import com.google.gerrit.reviewdb.client.PatchLineComment;
|
|||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
import com.google.gerrit.reviewdb.client.Project;
|
import com.google.gerrit.reviewdb.client.Project;
|
||||||
|
import com.google.gerrit.reviewdb.client.RefNames;
|
||||||
import com.google.gerrit.reviewdb.client.RevId;
|
import com.google.gerrit.reviewdb.client.RevId;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
|
import com.google.gerrit.reviewdb.server.ReviewDbUtil;
|
||||||
import com.google.gerrit.server.config.AllUsersName;
|
import com.google.gerrit.server.config.AllUsersName;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
import com.google.gerrit.server.git.ScanningChangeCacheImpl;
|
|
||||||
import com.google.gerrit.server.project.NoSuchChangeException;
|
import com.google.gerrit.server.project.NoSuchChangeException;
|
||||||
import com.google.gerrit.server.project.ProjectCache;
|
import com.google.gerrit.server.project.ProjectCache;
|
||||||
import com.google.gerrit.server.query.change.ChangeData;
|
import com.google.gerrit.server.query.change.ChangeData;
|
||||||
@@ -62,6 +63,7 @@ import org.eclipse.jgit.errors.ConfigInvalidException;
|
|||||||
import org.eclipse.jgit.lib.CommitBuilder;
|
import org.eclipse.jgit.lib.CommitBuilder;
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.PersonIdent;
|
import org.eclipse.jgit.lib.PersonIdent;
|
||||||
|
import org.eclipse.jgit.lib.Ref;
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.notes.NoteMap;
|
import org.eclipse.jgit.notes.NoteMap;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
@@ -70,8 +72,11 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.sql.Timestamp;
|
import java.sql.Timestamp;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/** View of a single {@link Change} based on the log of its notes branch. */
|
/** View of a single {@link Change} based on the log of its notes branch. */
|
||||||
public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
||||||
@@ -217,7 +222,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
* Instantiate ChangeNotes for a change that has been loaded by a batch read
|
* Instantiate ChangeNotes for a change that has been loaded by a batch read
|
||||||
* from the database.
|
* from the database.
|
||||||
*/
|
*/
|
||||||
public ChangeNotes createFromChangeOnlyWhenNotedbDisabled(Change change)
|
private ChangeNotes createFromChangeOnlyWhenNotedbDisabled(Change change)
|
||||||
throws OrmException {
|
throws OrmException {
|
||||||
checkState(!migration.readChanges(), "do not call"
|
checkState(!migration.readChanges(), "do not call"
|
||||||
+ " createFromChangeWhenNotedbDisabled when notedb is enabled");
|
+ " createFromChangeWhenNotedbDisabled when notedb is enabled");
|
||||||
@@ -231,8 +236,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
if (migration.readChanges()) {
|
if (migration.readChanges()) {
|
||||||
for (Project.NameKey project : projectCache.all()) {
|
for (Project.NameKey project : projectCache.all()) {
|
||||||
try (Repository repo = repoManager.openRepository(project)) {
|
try (Repository repo = repoManager.openRepository(project)) {
|
||||||
List<ChangeNotes> changes =
|
List<ChangeNotes> changes = scanNotedb(repo, db, project);
|
||||||
ScanningChangeCacheImpl.scanNotedb(this, repo, db, project);
|
|
||||||
for (ChangeNotes cn : changes) {
|
for (ChangeNotes cn : changes) {
|
||||||
if (predicate.apply(cn)) {
|
if (predicate.apply(cn)) {
|
||||||
m.put(project, cn);
|
m.put(project, cn);
|
||||||
@@ -250,6 +254,51 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
|
|||||||
}
|
}
|
||||||
return ImmutableListMultimap.copyOf(m);
|
return ImmutableListMultimap.copyOf(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ChangeNotes> scan(Repository repo, ReviewDb db,
|
||||||
|
Project.NameKey project) throws OrmException, IOException {
|
||||||
|
if (!migration.readChanges()) {
|
||||||
|
return scanDb(repo, db);
|
||||||
|
}
|
||||||
|
|
||||||
|
return scanNotedb(repo, db, project);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ChangeNotes> scanDb(Repository repo, ReviewDb db)
|
||||||
|
throws OrmException, IOException {
|
||||||
|
Map<String, Ref> refs =
|
||||||
|
repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES);
|
||||||
|
Set<Change.Id> ids = new LinkedHashSet<>();
|
||||||
|
for (Ref r : refs.values()) {
|
||||||
|
Change.Id id = Change.Id.fromRef(r.getName());
|
||||||
|
if (id != null) {
|
||||||
|
ids.add(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<ChangeNotes> notes = new ArrayList<>(ids.size());
|
||||||
|
// A batch size of N may overload get(Iterable), so use something smaller,
|
||||||
|
// but still >1.
|
||||||
|
for (List<Change.Id> batch : Iterables.partition(ids, 30)) {
|
||||||
|
for (Change change : db.changes().get(batch)) {
|
||||||
|
notes.add(createFromChangeOnlyWhenNotedbDisabled(change));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ChangeNotes> scanNotedb(Repository repo, ReviewDb db,
|
||||||
|
Project.NameKey project) throws OrmException, IOException {
|
||||||
|
Map<String, Ref> refs =
|
||||||
|
repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES);
|
||||||
|
List<ChangeNotes> changeNotes = new ArrayList<>(refs.size());
|
||||||
|
for (Ref r : refs.values()) {
|
||||||
|
Change.Id id = Change.Id.fromRef(r.getName());
|
||||||
|
if (id != null) {
|
||||||
|
changeNotes.add(create(db, project, id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return changeNotes;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Project.NameKey project;
|
private final Project.NameKey project;
|
||||||
|
|||||||
Reference in New Issue
Block a user