// returns a prefiltered list of elements; you still need to do a
// full-text search on those.
// If it returns null, you have to search all elements
static Cl deepDoubleWordIndex_lookupString(DoubleWordIndex> index, S query, O... _) {
optPar bool debug;
L ranges = index.wordRanges(query);
if (empty(ranges)) null;
new L> multiSetMaps; // snippet & positions for each word in query
// special case, just a single word in query
if (l(ranges) == 1 && first(ranges).start == 0 && first(ranges).end == l(query))
ret containingIC(index.index1.words(), word);
for (IntRange r : ranges) { // go through words in query
S word = substring(query, r);
Cl l; // all matching words in index
if (r.start == 0) { // look for ending of word - use reverse index
l = prefixSubSet(index.index2.words(), reversed(word));
if (empty(l)) ret emptyList();
// special loop that accounts for length of actual word
new MultiSetMap positions;
for (S fullWord : l)
for (WithIntArray entry : index.index1.index.get(fullWord)
positions.putAll(entry!, map(i -> i+l(fullWord)-l(word), toList(entry.array)));
multiSetMaps.add(positions);
continue;
} else if (r.end == l(query)) { // look for start of word
l = lmap reversed(prefixSubSet(index.index1.words(), word));
} else // look for complete word
l = ll(word);
if (empty(l)) ret emptyList();
// merge all positions
new MultiSetMap positions;
for (S fullWord : l)
for (WithIntArray entry : index.index1.index.get(fullWord)
positions.putAll(entry!, toList(entry.array));
multiSetMaps.add(positions);
}
for i over ranges: {
IntRange range = ranges.get(i);
MultiSetMap positions = multiSetMaps.get(i);
}
Set smallest = smallestCollection(sets), out = smallest;
for (Set set : sets) {
if (set == smallest) continue;
new Set out2;
for (A a : out)
if (set.contains(a))
out2.add(a);
out = out2;
}
ret out;
}