// 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; int nRanges = l(ranges); new Map> theMap; // for every snippet, a map of string position to word index // special case, just a single word in query if (l(ranges) == 1 && first(ranges).start == 0 && first(ranges).end == l(query)) { new L out; for (S fullWord : containingIC(index.index1.words(), query)) for (WithIntArray entry : index.index1.get(fullWord)) out.add(entry!); ret out; } for iWord over ranges: { // go through words in query IntRange r = ranges.get(iWord); 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 for (S fullWord : l) for (WithIntArray entry : index.index1.index.get(fullWord)) { MultiSetMap msm = theMap.get(entry!); if (msm == null) theMap.put(entry!, msm = new MultiSetMap); int ofs = l(fullWord)-l(word)-r.start; for (int i : entry.array) if (i+ofs >= 0) msm.put(i+ofs, iWord); } continue; } else if (r.end == l(query)) { // look for start of word l = lmap reversed(prefixSubSet(index.index2.words(), reversed(word))); } else // look for complete word l = ll(word); if (empty(l)) ret emptyList(); if (debug) print("word=" + word + ", fullWords=" + l); for (S fullWord : l) for (WithIntArray entry : index.index1.index.get(fullWord)) { MultiSetMap msm = theMap.get(entry!); if (msm == null) theMap.put(entry!, msm = new MultiSetMap); for (int i : entry.array) if (i-r.start >= 0) msm.put(i-r.start, iWord); } } if (debug) print("theMap size=" + l(theMap)); new L out; theLoop: for (A snippet, MultiSetMap msm : theMap) { for (int position, Set wordIndices : msm.data) { if (l(wordIndices) == nRanges) { out.add(snippet); continue theLoop; } } } ret out; }