/// <summary> /// Find the items containing *any word* starting with the word passed /// and add the union of all of them to the result set passed. /// </summary> /// <param name="prefix">Prefix to find</param> /// <param name="result">Result to which to add matches</param> public void WhereMatches(ByteBlock prefix, ShortSet result) { if (result == null) { throw new ArgumentNullException("result"); } // Split each word in the input value RangeSet prefixWords = _splitter.Split(prefix); // Shortcut: If only one word, add directly to result set if (prefixWords.Count == 1 && prefixWords.Ranges[0].Length == prefix.Length) { // Add matches for words starting with this prefix in every block foreach (WordIndexBlock block in _blocks) { block.WhereMatches(prefix, result); } } else { // We need to add (OR) the items which match all words (AND) in the split prefix ShortSet matchesForAllWords = null; ShortSet matchesForWord = new ShortSet(result.Capacity); // For each found word, add all matches for (int i = 0; i < prefixWords.Count; ++i) { Range word = prefixWords.Ranges[i]; ByteBlock wordBlock = new ByteBlock(prefix.Array, word.Index, word.Length); matchesForWord.Clear(); // Add matches for words starting with this prefix in every block foreach (WordIndexBlock block in _blocks) { block.WhereMatches(wordBlock, matchesForWord); } // AND matches for this word with each other word in the prefix if (matchesForAllWords == null) { matchesForAllWords = new ShortSet(result.Capacity); matchesForAllWords.Or(matchesForWord); } else { matchesForAllWords.And(matchesForWord); } } // OR matches for ALL words with the final result if (matchesForAllWords != null) { result.Or(matchesForAllWords); } } }
public void Index(ushort id, ByteBlock oldValue, ByteBlock newValue) { RangeSet oldValueWords = _splitter.Split(oldValue); RangeSet newValueWords = _splitter.Split(newValue); for (int i = 0; i < oldValueWords.Count; ++i) { Range word = oldValueWords.Ranges[i]; ByteBlock wordBlock = new ByteBlock(oldValue.Array, word.Index, word.Length); RemoveWord(id, wordBlock); } for (int i = 0; i < newValueWords.Count; ++i) { Range word = newValueWords.Ranges[i]; ByteBlock wordBlock = new ByteBlock(newValue.Array, word.Index, word.Length); AddWord(id, wordBlock); } }