Пример #1
0
        private int GetUnitIndexTour(string value, int segmentStart, byte[] buffer)
        {
            string word;
            long   position;
            long   length;

            for (int i = 0; i < SegmentSize / UnitBlockSize; i++)
            {
                if (UnicodeString.Decode(buffer, segmentStart + i * UnitBlockSize, 0, out word, "",
                                         out position, out length) < 0)
                {
                    return(i - 1);
                }

                int c = UnicodeString.Comparer(word, value);

                if (c > 0)
                {
                    return(i - 1);
                }
                else if (c == 0)
                {
                    return(i);
                }
            }

            return(SegmentSize / UnitBlockSize - 1);
        }
Пример #2
0
        public DDXUnit GetNext()
        {
            if (_Mode != Mode.Enum)
            {
                throw new System.IO.IOException(string.Format("DDX file: {0} is not enum mode. Can't be read!", _FilePath));
            }

            if (_SegmentEnum == null)
            {
                EnumReset();
            }

            string word;
            long   position;
            long   length;

            if (_CurrentPositionInUnitBlockEnum < 0)
            {
                return(null);
            }

            _CurrentPositionInUnitBlockEnum = UnicodeString.Decode(_SegmentEnum, _CurrentUnitIndexEnum * UnitBlockSize,
                                                                   _CurrentPositionInUnitBlockEnum,
                                                                   out word, _PreWordEnum, out position, out length);

            if (_CurrentPositionInUnitBlockEnum < 0)
            {
                _CurrentPositionInUnitBlockEnum = 0;
                _CurrentUnitIndexEnum++;

                if (_CurrentUnitIndexEnum * UnitBlockSize >= _SegmentEnum.Length)
                {
                    if (!Hubble.Framework.IO.File.ReadToBuffer(_File, _SegmentEnum))
                    {
                        return(null);
                    }
                    else
                    {
                        _CurrentUnitIndexEnum = 0;
                    }
                }

                _CurrentPositionInUnitBlockEnum = UnicodeString.Decode(_SegmentEnum, _CurrentUnitIndexEnum * UnitBlockSize,
                                                                       _CurrentPositionInUnitBlockEnum,
                                                                       out word, "", out position, out length);

                if (_CurrentPositionInUnitBlockEnum < 0)
                {
                    return(null);
                }
            }

            _PreWordEnum = word;
            return(new DDXUnit(word, position, length));
        }
Пример #3
0
        private void GetSegmentStartStrings()
        {
            List <string> strList = new List <string>(256);

            _File.Seek(0, SeekOrigin.Begin);
            byte[] segment = new byte[SegmentSize];

            if (Hubble.Framework.IO.File.ReadToBuffer(_File, segment))
            {
                do
                {
                    string word;
                    long   position;
                    long   length;

                    if (UnicodeString.Decode(segment, 0, out word, "", out position, out length) >= 0)
                    {
                        strList.Add(word);
                    }
                } while (Hubble.Framework.IO.File.ReadToBuffer(_File, segment));
            }

            _SegmentStartStrings = strList.ToArray();
        }
Пример #4
0
        public DDXUnit Find(string word)
        {
            lock (_ReadLockObj)
            {
                int segmentIndex = GetSegmentIndex(word);

                if (segmentIndex < 0)
                {
                    return(null);
                }
                else
                {
                    if (_DDXFileBuffer == null)
                    {
                        if (segmentIndex * SegmentSize >= _File.Length)
                        {
                            return(null);
                        }
                    }
                    else
                    {
                        if (segmentIndex * SegmentSize >= _DDXFileBuffer.Length)
                        {
                            return(null);
                        }
                    }

                    byte[] segmentBuffer;

                    int segmentStart;

                    if (_DDXFileBuffer == null)
                    {
                        _File.Seek(segmentIndex * SegmentSize, SeekOrigin.Begin);
                        segmentBuffer = new byte[SegmentSize];  //One segment include 32 unit blocks .
                        segmentStart  = 0;
                    }
                    else
                    {
                        segmentBuffer = _DDXFileBuffer;
                        segmentStart  = segmentIndex * SegmentSize;
                    }

                    if (_DDXFileBuffer == null)
                    {
                        if (!Hubble.Framework.IO.File.ReadToBuffer(_File, segmentBuffer))
                        {
                            throw new StoreException(string.Format("DDX Find fail, Word:{0} FilePostion = {1}",
                                                                   word, _File.Position));
                        }
                    }

                    int unitIndex;

                    if (segmentIndex == _SegmentStartStrings.Length - 1)
                    {
                        //Last segment
                        unitIndex = GetUnitIndexTour(word, segmentStart, segmentBuffer);
                    }
                    else
                    {
                        unitIndex = GetUnitIndexBin(word, segmentStart, segmentBuffer);
                    }

                    if (unitIndex < 0)
                    {
                        return(null);
                    }

                    string enumWord;
                    string preWord = "";
                    long   position;
                    long   length;

                    int positionInUnit = 0;

                    positionInUnit = UnicodeString.Decode(segmentBuffer, segmentStart + unitIndex * UnitBlockSize, positionInUnit,
                                                          out enumWord, preWord, out position, out length);

                    preWord = enumWord;

                    if (positionInUnit < 0)
                    {
                        return(null);
                    }

                    int c = UnicodeString.Comparer(enumWord, word);

                    while (c < 0)
                    {
                        positionInUnit = UnicodeString.Decode(segmentBuffer, segmentStart + unitIndex * UnitBlockSize, positionInUnit,
                                                              out enumWord, preWord, out position, out length);

                        preWord = enumWord;

                        if (positionInUnit < 0)
                        {
                            return(null);
                        }

                        c = UnicodeString.Comparer(enumWord, word);
                    }

                    if (c == 0)
                    {
                        return(new DDXUnit(word, position, length));
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
        }
Пример #5
0
        private int GetUnitIndexBin(string value, int segmentStart, byte[] buffer)
        {
            byte[] objArray = buffer;

            if (objArray.Length <= 0)
            {
                return(-1);
            }

            int lo = 0;
            int hi = (SegmentSize / UnitBlockSize) - 1;

            string word;
            long   position;
            long   length;

            while (lo <= hi)
            {
                // i might overflow if lo and hi are both large positive numbers.
                int i = lo + ((hi - lo) >> 1);

                if (UnicodeString.Decode(buffer, segmentStart + i * UnitBlockSize, 0, out word, "",
                                         out position, out length) < 0)
                {
                    throw new StoreException(string.Format("GetUnitIndexBin fail, Word:{0} SegmentStart:{1} index={2}",
                                                           word, segmentStart, i));
                }

                int c = UnicodeString.Comparer(word, value);

                if (c == 0)
                {
                    return(i);
                }

                if (c < 0)
                {
                    lo = i + 1;
                }
                else
                {
                    hi = i - 1;
                }
            }

            lo--;
            if (lo >= objArray.Length)
            {
                lo = objArray.Length - 1;
            }
            else if (lo < 0)
            {
                lo = 0;
            }

            if (UnicodeString.Decode(buffer, segmentStart + lo * UnitBlockSize, 0, out word, "",
                                     out position, out length) < 0)
            {
                throw new StoreException(string.Format("GetUnitIndexBin fail, Word:{0} SegmentStart:{1} index={2}",
                                                       word, segmentStart, lo));
            }

            if (UnicodeString.Comparer(word, value) <= 0)
            {
                return(lo);
            }
            else
            {
                return(-1);
            }
        }