Support exact match on file parts in file: operator

Keep the old "file" field around (using that name in the index for
backwards compatibility), but call it PATH in the code to reflect the
fact that it matches the full path. Add a new "filepart" repeated
field that splits the filename on '/' and adds each unique component
as a field value.

Use "path:" to search only the path, and "file:" to search either the
file or the full path. There is only support for single path
components or the full path, not arbitrary sequences of subcomponents.
The latter is possible but would result in combinatorial blowup of
terms. If users really want to search on that, they can use multiple
"file:" terms (discarding ordering) or use regex search.

Regex search is still over the entire path, but this is implemented at
the ChangeQueryBuilder level and may be changed in the future.

Change-Id: I4f6e06bc3c07989f96e4e74e64113f521c05b9e3
This commit is contained in:
Dave Borowitz
2013-12-27 11:38:01 -08:00
committed by Shawn Pearce
parent a76877cfb0
commit 64e0b0762f
12 changed files with 194 additions and 43 deletions

View File

@@ -14,6 +14,7 @@
package com.google.gerrit.server.index;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gerrit.reviewdb.client.Account;
@@ -160,10 +161,11 @@ public class ChangeField {
}
};
/** List of filenames modified in the current patch set. */
public static final FieldDef<ChangeData, Iterable<String>> FILE =
/** List of full file paths modified in the current patch set. */
public static final FieldDef<ChangeData, Iterable<String>> PATH =
new FieldDef.Repeatable<ChangeData, String>(
ChangeQueryBuilder.FIELD_FILE, FieldType.EXACT, false) {
// Named for backwards compatibility.
"file", FieldType.EXACT, false) {
@Override
public Iterable<String> get(ChangeData input, FillArgs args)
throws OrmException {
@@ -171,6 +173,28 @@ public class ChangeField {
}
};
public static Set<String> getFileParts(ChangeData cd) throws OrmException {
Splitter s = Splitter.on('/').omitEmptyStrings();
Set<String> r = Sets.newHashSet();
for (String path : cd.currentFilePaths()) {
for (String part : s.split(path)) {
r.add(part);
}
}
return r;
}
/** Components of each file path modified in the current patch set. */
public static final FieldDef<ChangeData, Iterable<String>> FILE_PART =
new FieldDef.Repeatable<ChangeData, String>(
"filepart", FieldType.EXACT, false) {
@Override
public Iterable<String> get(ChangeData input, FillArgs args)
throws OrmException {
return getFileParts(input);
}
};
/** Owner/creator of the change. */
public static final FieldDef<ChangeData, Integer> OWNER =
new FieldDef.Single<ChangeData, Integer>(