コード例 #1
0
            internal virtual void AdvanceWord(int targetWordNum)
            {
                Debug.Assert(targetWordNum > WordNum);
                int delta = targetWordNum - WordNum;

                if (delta <= AllOnesLength + DirtyLength + 1)
                {
                    SkipDirtyBytes(delta - 1);
                }
                else
                {
                    SkipDirtyBytes();
                    Debug.Assert(DirtyLength == 0);
                    if (delta > IndexThreshold_Renamed)
                    {
                        // use the index
                        int i        = ForwardBinarySearch(targetWordNum);
                        int position = (int)Positions.Get(i);
                        if (position > @in.Position) // if the binary search returned a backward offset, don't move
                        {
                            WordNum      = (int)WordNums.Get(i) - 1;
                            @in.Position = position;
                            SequenceNum  = i * IndexInterval - 1;
                        }
                    }

                    while (true)
                    {
                        if (!ReadSequence())
                        {
                            return;
                        }
                        delta = targetWordNum - WordNum;
                        if (delta <= AllOnesLength + DirtyLength + 1)
                        {
                            if (delta > 1)
                            {
                                SkipDirtyBytes(delta - 1);
                            }
                            break;
                        }
                        SkipDirtyBytes();
                    }
                }

                NextWord();
            }
コード例 #2
0
            internal virtual int ForwardBinarySearch(int targetWordNum)
            {
                // advance forward and double the window at each step
                int indexSize = (int)WordNums.Size();
                int lo = SequenceNum / IndexInterval, hi = lo + 1;

                Debug.Assert(SequenceNum == -1 || WordNums.Get(lo) <= WordNum);
                Debug.Assert(lo + 1 == WordNums.Size() || WordNums.Get(lo + 1) > WordNum);
                while (true)
                {
                    if (hi >= indexSize)
                    {
                        hi = indexSize - 1;
                        break;
                    }
                    else if (WordNums.Get(hi) >= targetWordNum)
                    {
                        break;
                    }
                    int newLo = hi;
                    hi += (hi - lo) << 1;
                    lo  = newLo;
                }

                // we found a window containing our target, let's binary search now
                while (lo <= hi)
                {
                    int mid        = (int)((uint)(lo + hi) >> 1);
                    int midWordNum = (int)WordNums.Get(mid);
                    if (midWordNum <= targetWordNum)
                    {
                        lo = mid + 1;
                    }
                    else
                    {
                        hi = mid - 1;
                    }
                }
                Debug.Assert(WordNums.Get(hi) <= targetWordNum);
                Debug.Assert(hi + 1 == WordNums.Size() || WordNums.Get(hi + 1) > targetWordNum);
                return(hi);
            }