Add method on Index to look up a single document by key
Now that we have Java 8, it is easy to provide a default implementation using a default method. The only thing subinterfaces need to provide is a way to construct a predicate matching exactly one document by key. Index backend authors may also choose to provide a more efficient implementation if necessary. Change-Id: I7d9de2f9c947ced9411b69ed39606dc4ba0b599a
This commit is contained in:
@@ -17,8 +17,11 @@ package com.google.gerrit.server.index;
|
||||
import com.google.gerrit.server.query.DataSource;
|
||||
import com.google.gerrit.server.query.Predicate;
|
||||
import com.google.gerrit.server.query.QueryParseException;
|
||||
import com.google.gwtorm.server.OrmException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Secondary index implementation for arbitrary documents.
|
||||
@@ -90,6 +93,44 @@ public interface Index<K, V> {
|
||||
DataSource<V> getSource(Predicate<V> p, QueryOptions opts)
|
||||
throws QueryParseException;
|
||||
|
||||
/**
|
||||
* Get a single document from the index.
|
||||
*
|
||||
* @param key document key.
|
||||
* @param opts query options. Options that do not make sense in the context of
|
||||
* a single document, such as start, will be ignored.
|
||||
* @return a single document if present.
|
||||
* @throws IOException
|
||||
*/
|
||||
default Optional<V> get(K key, QueryOptions opts) throws IOException {
|
||||
opts = opts.withStart(0).withLimit(2);
|
||||
List<V> results;
|
||||
try {
|
||||
results = getSource(keyPredicate(key), opts).read().toList();
|
||||
} catch (QueryParseException e) {
|
||||
throw new IOException("Unexpected QueryParseException during get()", e);
|
||||
} catch (OrmException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
switch (results.size()) {
|
||||
case 0:
|
||||
return Optional.empty();
|
||||
case 1:
|
||||
return Optional.of(results.get(0));
|
||||
default:
|
||||
throw new IOException("Multiple results found in index for key "
|
||||
+ key + ": " + results);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a predicate that looks up a single document by key.
|
||||
*
|
||||
* @param key document key.
|
||||
* @return a single predicate.
|
||||
*/
|
||||
Predicate<V> keyPredicate(K key);
|
||||
|
||||
/**
|
||||
* Mark whether this index is up-to-date and ready to serve reads.
|
||||
*
|
||||
|
||||
@@ -18,9 +18,16 @@ import com.google.gerrit.reviewdb.client.Account;
|
||||
import com.google.gerrit.server.account.AccountState;
|
||||
import com.google.gerrit.server.index.Index;
|
||||
import com.google.gerrit.server.index.IndexDefinition;
|
||||
import com.google.gerrit.server.query.Predicate;
|
||||
import com.google.gerrit.server.query.account.AccountPredicates;
|
||||
|
||||
public interface AccountIndex extends Index<Account.Id, AccountState> {
|
||||
public interface Factory extends
|
||||
IndexDefinition.IndexFactory<Account.Id, AccountState, AccountIndex> {
|
||||
}
|
||||
|
||||
@Override
|
||||
default Predicate<AccountState> keyPredicate(Account.Id id) {
|
||||
return AccountPredicates.id(id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,10 +17,17 @@ package com.google.gerrit.server.index.change;
|
||||
import com.google.gerrit.reviewdb.client.Change;
|
||||
import com.google.gerrit.server.index.Index;
|
||||
import com.google.gerrit.server.index.IndexDefinition;
|
||||
import com.google.gerrit.server.query.Predicate;
|
||||
import com.google.gerrit.server.query.change.ChangeData;
|
||||
import com.google.gerrit.server.query.change.LegacyChangeIdPredicate;
|
||||
|
||||
public interface ChangeIndex extends Index<Change.Id, ChangeData> {
|
||||
public interface Factory extends
|
||||
IndexDefinition.IndexFactory<Change.Id, ChangeData, ChangeIndex> {
|
||||
}
|
||||
|
||||
@Override
|
||||
default Predicate<ChangeData> keyPredicate(Change.Id id) {
|
||||
return new LegacyChangeIdPredicate(id);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user