ExportReviewNotes: Load changes from notedb if enabled

This requires a new method in ChangeNotes.Factory to get changes notes
by project.

CreateReviewNotes#createCodeReviewNote needs the change notes, so pass
in the change notes, instead of passing in the change and loading
the change notes a second time.

ChangeNotes.Factory doesn't support batch loading of changes yet. Due
to this batch loading changes still accesses the database directly
when notedb is disabled. For changes loaded in such a batch we want to
instantiate ChangeNotes without reloading the change. Add a special
method for this to ChangeNotes.Factory. This method is not supposed to
be used when notedb is enabled.

Change-Id: Ifd01276a607fb5ab4a36322112d0b7aaa0f0ff70
Signed-off-by: Edwin Kempin <ekempin@google.com>
This commit is contained in:
Edwin Kempin 2016-02-12 10:52:53 +01:00 committed by David Pursehouse
parent 9e504cf85d
commit 3c377580a2
3 changed files with 69 additions and 7 deletions

View File

@ -16,9 +16,11 @@ package com.google.gerrit.server.git;
import static com.google.gerrit.server.git.SearchingChangeCacheImpl.ID_CACHE;
import com.google.common.base.Function;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
@ -120,7 +122,7 @@ public class ScanningChangeCacheImpl implements ChangeCache {
return scanDb(repo, db);
}
return scanNotedb(notesFactory, repo, db, project);
return scanChangesFromNotedb(notesFactory, repo, db, project);
}
public static List<Change> scanDb(Repository repo, ReviewDb db)
@ -143,18 +145,30 @@ public class ScanningChangeCacheImpl implements ChangeCache {
return changes;
}
public static List<Change> scanNotedb(ChangeNotes.Factory notesFactory,
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<Change> changes = new ArrayList<>(refs.size());
List<ChangeNotes> changeNotes = 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());
changeNotes.add(notesFactory.create(db, project, id));
}
}
return changes;
return changeNotes;
}
}

View File

@ -20,7 +20,9 @@ import static com.google.gerrit.server.notedb.ChangeNoteUtil.GERRIT_PLACEHOLDER_
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.base.Strings;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableListMultimap;
import com.google.common.collect.ImmutableMap;
@ -28,6 +30,7 @@ import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSetMultimap;
import com.google.common.collect.ImmutableSortedMap;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.ListMultimap;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import com.google.gerrit.common.data.SubmitRecord;
@ -45,7 +48,9 @@ import com.google.gerrit.reviewdb.server.ReviewDbUtil;
import com.google.gerrit.server.config.AllUsersName;
import com.google.gerrit.server.config.AllUsersNameProvider;
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.ProjectCache;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
@ -57,6 +62,7 @@ import org.eclipse.jgit.errors.ConfigInvalidException;
import org.eclipse.jgit.lib.CommitBuilder;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.notes.NoteMap;
import org.eclipse.jgit.revwalk.RevWalk;
import org.slf4j.Logger;
@ -116,17 +122,20 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
private final NotesMigration migration;
private final AllUsersNameProvider allUsersProvider;
private final Provider<InternalChangeQuery> queryProvider;
private final ProjectCache projectCache;
@VisibleForTesting
@Inject
public Factory(GitRepositoryManager repoManager,
NotesMigration migration,
AllUsersNameProvider allUsersProvider,
Provider<InternalChangeQuery> queryProvider) {
Provider<InternalChangeQuery> queryProvider,
ProjectCache projectCache) {
this.repoManager = repoManager;
this.migration = migration;
this.allUsersProvider = allUsersProvider;
this.queryProvider = queryProvider;
this.projectCache = projectCache;
}
public ChangeNotes createChecked(ReviewDb db, Change c)
@ -190,6 +199,45 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
return new ChangeNotes(repoManager, migration, allUsersProvider,
change.getProject(), change).load();
}
// TODO(ekempin): Remove when database backend is deleted
/**
* Instantiate ChangeNotes for a change that has been loaded by a batch read
* from the database.
*/
public ChangeNotes createFromChangeOnlyWhenNotedbDisabled(Change change)
throws OrmException {
checkState(!migration.readChanges(), "do not call"
+ " createFromChangeWhenNotedbDisabled when notedb is enabled");
return new ChangeNotes(repoManager, migration, allUsersProvider,
change.getProject(), change).load();
}
public ListMultimap<Project.NameKey, ChangeNotes> create(ReviewDb db,
Predicate<ChangeNotes> predicate) throws IOException, OrmException {
ListMultimap<Project.NameKey, ChangeNotes> m = ArrayListMultimap.create();
if (migration.readChanges()) {
for (Project.NameKey project : projectCache.all()) {
try (Repository repo = repoManager.openRepository(project)) {
List<ChangeNotes> changes =
ScanningChangeCacheImpl.scanNotedb(this, repo, db, project);
for (ChangeNotes cn : changes) {
if (predicate.apply(cn)) {
m.put(project, cn);
}
}
}
}
} else {
for (Change change : db.changes().all()) {
ChangeNotes notes = createFromChangeOnlyWhenNotedbDisabled(change);
if (predicate.apply(notes)) {
m.put(change.getProject(), notes);
}
}
}
return ImmutableListMultimap.copyOf(m);
}
}
private final Project.NameKey project;

@ -1 +1 @@
Subproject commit d383ad3b52ecd2bf0f082b5c03e8e4dfcc121350
Subproject commit 47c74e2da9443e028d8d52d95791e0cd15add822