Пример #1
0
        /// <summary>
        /// Searches the index for items
        /// </summary>
        /// <param name="tokens">The list of tokens which have to occur in the document in the given order</param>
        /// <returns>An enumerable returning the matched items</returns>
        public IEnumerable <IndexItem> Search(Token[] tokens)
        {
            // return all lines if no tokens given
            if (tokens.Length == 0)
            {
                var files     = new List <Tuple <string, string, IReadOnlyList <uint>, IReadOnlyList <uint> > >();
                var fileStart = 0;
                foreach (var file in _lines.OrderBy(i => i.File, _comparer).ThenBy(i => i.Member, _comparer))
                {
                    var lines = new EliasFanoList((uint)(fileStart + file.Positions.Count), file.Positions.Count, Enumerable.Range(fileStart, file.Positions.Count).Select(i => (uint)i));
                    files.Add(new Tuple <string, string, IReadOnlyList <uint>, IReadOnlyList <uint> >(file.File, file.Member, file.Positions, lines));
                    fileStart += file.Positions.Count;
                }

                // return the original compressed index in case we want to compress it later on (highly possible when returning all lines -> full view of log is visible)
                return(new DirectIndex(files));
            }
            else
            {
                return(SearchIterator(tokens));
            }
        }
Пример #2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EliasFanoEnumerator"/>
 /// </summary>
 /// <param name="collection">List to enumerate on</param>
 public EliasFanoEnumerator(EliasFanoList collection)
 {
     _collection    = collection;
     _lowerBitsMask = (uint)(1 << _collection._lowerBitCount) - 1;
     Reset();
 }
Пример #3
0
        /// <summary>
        /// Adds an item to the list
        /// </summary>
        /// <param name="item">Item to add</param>
        public void Add(uint item)
        {
            if (item < _lastAddedItem)
            {
                throw new InvalidOperationException("Items must be added in monotonically increasing order");
            }

            if (item > _universe)
            {
                // extend the universe and recompress the list
                var temp = new EliasFanoList(_universe * 2, Count + 1, this.Concat(new[] { item }));
                _lowerBitCount           = temp._lowerBitCount;
                _universe                = temp._universe;
                _skipQuantum             = temp._skipQuantum;
                _indexQuantum            = temp._indexQuantum;
                _count                   = temp._count;
                _upperBitCount           = temp._upperBitCount;
                _lowerBits               = temp._lowerBits;
                _upperBits               = temp._upperBits;
                _skipPointers            = temp._skipPointers;
                _skipPointerCount        = temp._skipPointerCount;
                _indexPointers           = temp._indexPointers;
                _indexPointerCount       = temp._indexPointerCount;
                _lastAddedItem           = temp._lastAddedItem;
                _negatedUnaryReadCounter = temp._negatedUnaryReadCounter;
                _unaryReadCounter        = temp._unaryReadCounter;
                _indexEnumerator.Reset();
            }
            else
            {
                // store the lower bits
                var lowerBitMask    = (1 << _lowerBitCount) - 1;
                var lowerBits       = item & lowerBitMask;
                var lowerBitCounter = 0;
                var lowerBitPointer = _lowerBitCount * _count;
                while (lowerBitCounter < _lowerBitCount)
                {
                    var byteOffset = (lowerBitPointer + lowerBitCounter) / 32;
                    var bitOffset  = (lowerBitPointer + lowerBitCounter) % 32;

                    // resize the array if required
                    if (byteOffset >= _lowerBits.Length)
                    {
                        Array.Resize(ref _lowerBits, (int)Math.Ceiling(byteOffset * 1.5));
                    }

                    _lowerBits[byteOffset] |= (uint)(lowerBits << bitOffset);
                    lowerBitCounter        += 32 - bitOffset;
                    lowerBits >>= 32 - bitOffset;
                }

                lowerBitPointer += _lowerBitCount;

                // get the upper bits to store and the difference to the previous upper bits
                var upperBits = item >> _lowerBitCount;
                var delta     = upperBits - (_lastAddedItem >> _lowerBitCount);

                // build the negated unary skip list
                for (var i = 0U; i < delta; i++)
                {
                    _negatedUnaryReadCounter += 1;
                    if (_negatedUnaryReadCounter >= _skipQuantum)
                    {
                        // grow the skip pointer array if required
                        if (_skipPointerCount == _skipPointers.Length)
                        {
                            Array.Resize(ref _skipPointers, (int)Math.Ceiling(_skipPointers.Length * 1.5));
                        }
                        _skipPointers[_skipPointerCount++] = _upperBitCount + i + 1;
                        _negatedUnaryReadCounter           = 0;
                    }
                }

                // store the delta of the upper bits in unary encoding
                _upperBitCount += delta;
                if (_upperBitCount / 32 >= _upperBits.Length)
                {
                    Array.Resize(ref _upperBits, (int)Math.Ceiling(_upperBitCount * 1.5));
                }
                _upperBits[_upperBitCount / 32] |= (uint)(1 << (int)(_upperBitCount % 32));
                _upperBitCount += 1;

                // build the skip list for direct indexing
                _unaryReadCounter += 1;
                if (_unaryReadCounter > _indexQuantum)
                {
                    if (_indexPointerCount == _indexPointers.Length)
                    {
                        Array.Resize(ref _indexPointers, (int)Math.Ceiling(_indexPointers.Length * 1.5));
                    }
                    _indexPointers[_indexPointerCount++] = _upperBitCount;
                    _unaryReadCounter = 1;
                }

                _count        += 1;
                _lastAddedItem = item;
            }
        }