internal int AddEntry(int additionalLengthNeeded, byte[] newData, int entryIndex) { var newCount = Count + 1; SetCountToSectorData(newData, newCount); var insertOfs = OffsetOfIndex(entryIndex); Array.Copy(Data, HeaderSize, newData, HeaderSize, entryIndex * HeaderForEntry); var additionalLengthNeededWOHeader = additionalLengthNeeded - HeaderForEntry; Array.Copy(Data, insertOfs, newData, insertOfs + additionalLengthNeeded, TotalLength - insertOfs); Array.Copy( Data, HeaderSize + Count * HeaderForEntry, newData, HeaderSize + newCount * HeaderForEntry, insertOfs - (HeaderSize + Count * HeaderForEntry)); for (int i = newCount - 1; i >= entryIndex; i--) { ushort o; if (i == 0) { o = (ushort)additionalLengthNeededWOHeader; } else { o = (ushort)(PackUnpack.UnpackUInt16LE(Data, HeaderSize + (i - 1) * HeaderForEntry) + additionalLengthNeededWOHeader); } PackUnpack.PackUInt16LE(newData, HeaderSize + i * HeaderForEntry, o); } return(insertOfs + HeaderForEntry); }
internal bool MoveNext() { if (_pos + 1 >= _count) { return(false); } _ofs = FirstOffset + PackUnpack.UnpackUInt16LE(_data, HeaderSize + _pos * HeaderForEntry); _pos++; _keyLen = -1; return(true); }
internal int OffsetOfIndex(int index) { if (index == 0) { return(FirstOffset); } if (index == _count) { return(TotalLength); } return(FirstOffset + PackUnpack.UnpackUInt16LE(_data, HeaderSize + (index - 1) * HeaderForEntry)); }
internal void MoveTo(int pos) { Debug.Assert(pos >= 0); Debug.Assert(pos < _count); if (pos == 0) { MoveFirst(); return; } _pos = pos; _ofs = FirstOffset + PackUnpack.UnpackUInt16LE(_data, HeaderSize + (pos - 1) * HeaderForEntry); _keyLen = -1; }
internal void ResizeValue(byte[] newData, long newSize) { var currentEntrySize = CurrentEntrySize; var newEntrySize = CalcEntrySize(KeyLen, newSize); int withValuePtr = 0; if (HasValueSectorPtr && newSize > MaxValueLenInline) { withValuePtr = KeyValueDB.PtrDownSize; } // preserves all before current item including current sizes + key int ofs = EntryOffset + PackUnpack.LengthVUInt((uint)KeyLen); if (!ReferenceEquals(Data, newData)) { Array.Copy(Data, 0, newData, 0, ofs); } if (newSize > ValueLen) // because resize could be inplace bytes have to be copied correct order { // preserves all after current item Array.Copy(Data, EntryOffset + currentEntrySize - withValuePtr, newData, EntryOffset + newEntrySize - withValuePtr, TotalLength - EntryOffset - currentEntrySize + withValuePtr); // preserves key of current item Array.Copy(Data, KeyOffset, newData, ofs + PackUnpack.LengthVUInt((ulong)newSize), ValueOffset - KeyOffset); } else { // preserves key of current item Array.Copy(Data, KeyOffset, newData, ofs + PackUnpack.LengthVUInt((ulong)newSize), ValueOffset - KeyOffset); // preserves all after current item Array.Copy(Data, EntryOffset + currentEntrySize - withValuePtr, newData, EntryOffset + newEntrySize - withValuePtr, TotalLength - EntryOffset - currentEntrySize + withValuePtr); } PackUnpack.PackVUInt(newData, ref ofs, (ulong)newSize); _data = newData; _valueLen = newSize; _ofsAfterKeyAndValueLen = ofs; var delta = newEntrySize - currentEntrySize; for (int i = _pos; i < _count; i++) { var o = HeaderSize + HeaderForEntry * i; PackUnpack.PackUInt16LE(_data, o, (ushort)(PackUnpack.UnpackUInt16LE(_data, o) + delta)); } }
internal SectorPtr GetChildSectorPtr(int index, ref long keyIndex) { if (index == 0) { return(FirstChildSectorPtr); } keyIndex += FirstChildKeyCount; var firstOffset = FirstOffset; _ofs = firstOffset; _pos = 0; _keyLen = -1; while (_pos < index - 1) { keyIndex += ChildKeyCount; _ofs = firstOffset + PackUnpack.UnpackUInt16LE(_data, HeaderSize + _pos * HeaderForEntry); _pos++; } return(ChildSectorPtr); }
internal static uint CountFromSectorData(byte[] data) { return(PackUnpack.UnpackUInt16LE(data, 0)); }