Ejemplo n.º 1
0
        /// <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);
                }
            }
        }
Ejemplo n.º 2
0
            /// <summary>
            ///  Get the IDs listed in the set for a given word and add them
            ///  to a result ShortSet.
            /// </summary>
            /// <param name="setId">ID of set/word to add</param>
            /// <param name="result">ShortSet to which to add results</param>
            public unsafe void GetInSet(ushort setId, ShortSet result)
            {
                ByteBlock set = _sets[setId];

                fixed(byte *array = set.Array)
                {
                    if (set.Length < DenseSetLengthCutoff)
                    {
                        // Sparse Set: Add values as individual ushorts.
                        ushort *valuesForWord = (ushort *)(array + set.Index);
                        ushort  usedLength    = FindUsedLength(valuesForWord, (ushort)(set.Length / 2));
                        result.Or(valuesForWord, usedLength);
                    }
                    else
                    {
                        // Dense Set: Add values as ulong bits.
                        ulong *bitsForWord = (ulong *)(array + set.Index);
                        result.Or(bitsForWord, (ushort)(set.Length / 8));
                    }
                }
            }