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); }
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)); }
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(); }
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); } } } }
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); } }