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); }
private int GetSegmentIndex(string value) { string[] objArray = _SegmentStartStrings; if (objArray.Length <= 0) { return(-1); } int lo = 0; int hi = objArray.Length - 1; while (lo <= hi) { // i might overflow if lo and hi are both large positive numbers. int i = lo + ((hi - lo) >> 1); int c = UnicodeString.Comparer(objArray[i], 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.Comparer(objArray[lo], value) <= 0) { return(lo); } else { return(-1); } }
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); } }