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 static void RecalculateHeader(byte[] data, int count) { var ofs1 = HeaderSize + HeaderForEntry * count; var ofs = ofs1; for (int i = 0; i < count; i++) { ofs += CalcEntrySize(PackUnpack.UnpackInt32LE(data, ofs)); PackUnpack.PackUInt16LE(data, HeaderSize + HeaderForEntry * i, (ushort)(ofs - ofs1)); } }
internal static void RecalculateHeader(byte[] data, int count) { var ofs1 = HeaderSize + HeaderForEntry * count; var ofs = ofs1; for (int i = 0; i < count; i++) { var keyLen = (int)PackUnpack.UnpackVUInt(data, ref ofs); var valueLen = (long)PackUnpack.UnpackVUInt(data, ref ofs); ofs += CalcEntrySizeWOLengths(keyLen, valueLen); PackUnpack.PackUInt16LE(data, HeaderSize + HeaderForEntry * i, (ushort)(ofs - ofs1)); } }
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 static void SetCountToSectorData(byte[] data, int count) { Debug.Assert(count > 0 && count < 128 * 256); PackUnpack.PackUInt16LE(data, 0, (ushort)count); }
internal static void SetOneEntryCount(byte[] data, int entrySize) { SetCountToSectorData(data, 1); PackUnpack.PackUInt16LE(data, HeaderSize, (ushort)entrySize); }