use of com.google.gerrit.index.QueryOptions in project gerrit by GerritCodeReview.
the class QueryProcessor method query.
private List<QueryResult<T>> query(@Nullable List<String> queryStrings, List<Predicate<T>> queries) throws QueryParseException {
long startNanos = System.nanoTime();
checkState(!used.getAndSet(true), "%s has already been used", getClass().getSimpleName());
int cnt = queries.size();
if (queryStrings != null) {
int qs = queryStrings.size();
checkArgument(qs == cnt, "got %s query strings but %s predicates", qs, cnt);
}
if (cnt == 0) {
return ImmutableList.of();
}
if (isDisabled()) {
return disabledResults(queryStrings, queries);
}
logger.atFine().log("Executing %d %s index queries for %s", cnt, schemaDef.getName(), callerFinder.findCallerLazy());
List<QueryResult<T>> out;
try {
// Parse and rewrite all queries.
List<Integer> limits = new ArrayList<>(cnt);
List<Predicate<T>> predicates = new ArrayList<>(cnt);
List<DataSource<T>> sources = new ArrayList<>(cnt);
int queryCount = 0;
for (Predicate<T> q : queries) {
checkSupportedForQueries(q);
int limit = getEffectiveLimit(q);
limits.add(limit);
if (limit == getBackendSupportedLimit()) {
limit--;
}
int page = (start / limit) + 1;
if (page > indexConfig.maxPages()) {
throw new QueryParseException("Cannot go beyond page " + indexConfig.maxPages() + " of results");
}
// Always bump limit by 1, even if this results in exceeding the permitted
// max for this user. The only way to see if there are more entities is to
// ask for one more result from the query.
QueryOptions opts = createOptions(indexConfig, start, limit + 1, getRequestedFields());
logger.atFine().log("Query options: %s", opts);
Predicate<T> pred = rewriter.rewrite(q, opts);
if (enforceVisibility) {
pred = enforceVisibility(pred);
}
predicates.add(pred);
logger.atFine().log("%s index query[%d]:\n%s", schemaDef.getName(), queryCount++, pred instanceof IndexedQuery ? pred.getChild(0) : pred);
@SuppressWarnings("unchecked") DataSource<T> s = (DataSource<T>) pred;
sources.add(s);
}
// Run each query asynchronously, if supported.
List<ResultSet<T>> matches = new ArrayList<>(cnt);
for (DataSource<T> s : sources) {
matches.add(s.read());
}
out = new ArrayList<>(cnt);
for (int i = 0; i < cnt; i++) {
ImmutableList<T> matchesList = matches.get(i).toList();
logger.atFine().log("Matches[%d]:\n%s", i, lazy(() -> matchesList.stream().map(this::formatForLogging).collect(toList())));
out.add(QueryResult.create(queryStrings != null ? queryStrings.get(i) : null, predicates.get(i), limits.get(i), matchesList));
}
// Only measure successful queries that actually touched the index.
metrics.executionTime.record(schemaDef.getName(), System.nanoTime() - startNanos, TimeUnit.NANOSECONDS);
} catch (StorageException e) {
Optional<QueryParseException> qpe = findQueryParseException(e);
if (qpe.isPresent()) {
throw new QueryParseException(qpe.get().getMessage(), e);
}
throw e;
}
return out;
}
use of com.google.gerrit.index.QueryOptions in project gerrit by GerritCodeReview.
the class AbstractFakeIndex method getSource.
@Override
public DataSource<V> getSource(Predicate<V> p, QueryOptions opts) {
List<V> results;
synchronized (indexedDocuments) {
results = indexedDocuments.values().stream().map(doc -> valueFor(doc)).filter(doc -> p.asMatchable().match(doc)).sorted(sortingComparator()).skip(opts.start()).limit(opts.limit()).collect(toImmutableList());
}
return new DataSource<>() {
@Override
public int getCardinality() {
return results.size();
}
@Override
public ResultSet<V> read() {
return new ListResultSet<>(results);
}
@Override
public ResultSet<FieldBundle> readRaw() {
ImmutableList.Builder<FieldBundle> fieldBundles = ImmutableList.builder();
for (V result : results) {
ImmutableListMultimap.Builder<String, Object> fields = ImmutableListMultimap.builder();
for (FieldDef<V, ?> field : getSchema().getFields().values()) {
if (field.get(result) == null) {
continue;
}
if (field.isRepeatable()) {
fields.putAll(field.getName(), (Iterable<?>) field.get(result));
} else {
fields.put(field.getName(), field.get(result));
}
}
fieldBundles.add(new FieldBundle(fields.build()));
}
return new ListResultSet<>(fieldBundles.build());
}
};
}
use of com.google.gerrit.index.QueryOptions in project gerrit by GerritCodeReview.
the class InitIT method indexesAllProjectsAndAllUsers.
@Test
public void indexesAllProjectsAndAllUsers() throws Exception {
initSite();
try (ServerContext ctx = startServer()) {
ProjectIndexCollection projectIndex = ctx.getInjector().getInstance(ProjectIndexCollection.class);
Project.NameKey allProjects = ctx.getInjector().getInstance(AllProjectsName.class);
Project.NameKey allUsers = ctx.getInjector().getInstance(AllUsersName.class);
QueryOptions opts = QueryOptions.create(IndexConfig.createDefault(), 0, 1, ImmutableSet.of("name"));
Optional<ProjectData> allProjectsData = projectIndex.getSearchIndex().get(allProjects, opts);
assertThat(allProjectsData).isPresent();
Optional<ProjectData> allUsersData = projectIndex.getSearchIndex().get(allUsers, opts);
assertThat(allUsersData).isPresent();
}
}
Aggregations