!7 cprint SnippetsDoubleWordIndex { transient DoubleWordIndex> wordIndex; // inner string = snippet ID, array = word positions in snippet start-thread { time "Make double word index" { print("Making index"); new DoubleWordIndex> wordIndex; for (virtual CSnippet sn : dm_allSnippets()) { S snippetID = (S) rcall snippetID(sn); S text = cast rcall text(sn); MultiMap positions = ciMultiMap(); for (IntRange r : wordIndex.wordRanges(text)) positions.put(substring(text, r), r.start); for (S word, L indices : positions.asMap()) wordIndex.addWord(new WithIntArray(toIntArray(indices), snippetID), word); } setField(+wordIndex); } print("Indexed " + nWords(wordIndex.numWords())); } // API // may return null (no pre-search result) Cl snippetsContainingTextIC_preSearch(S query, O... _) { ret deepDoubleWordIndex_lookupString(wordIndex, query, _); } }