internal void SavePage(Page <T> node) { lock (_fileLock) { int pnum = node.DiskPageNumber; if (pnum > _LastPageNumber) { throw new Exception("should not be here: page out of bounds"); } SeekPage(pnum); byte[] page = new byte[_PageLength]; byte[] blockheader = CreateBlockHeader(0, (ushort)node.tree.Count, node.RightPageNumber); Buffer.BlockCopy(blockheader, 0, page, 0, blockheader.Length); int index = blockheader.Length; int i = 0; byte[] b = null; T[] keys = node.tree.Keys(); Array.Sort(keys); // sort keys on save for read performance // node children foreach (var kp in keys) { var val = node.tree[kp]; int idx = index + _rowSize * i++; // key bytes byte[] kk = _T.GetBytes(kp); byte size = (byte)kk.Length; if (size > _maxKeySize) { size = _maxKeySize; } // key size = 1 byte page[idx] = size; Buffer.BlockCopy(kk, 0, page, idx + 1, page[idx]); // offset = 4 bytes b = Helper.GetBytes(val.RecordNumber, false); Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize, b.Length); // duplicatepage = 4 bytes b = Helper.GetBytes(val.DuplicateBitmapNumber, false); Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize + 4, b.Length); } _file.Write(page, 0, page.Length); } }
public bool RemoveKey(T key) { // remove and store key in storage file byte[] bkey = _T.GetBytes(key); MemoryStream ms = new MemoryStream(); ms.Write(Helper.GetBytes(bkey.Length, false), 0, 4); ms.Write(bkey, 0, bkey.Length); return(Delete(key, ms.ToArray())); }
public int WriteData(T key, byte[] data, bool deleted) { byte[] k = _T.GetBytes(key); int kl = k.Length; // seek end of file long offset = _lastWriteOffset; byte[] hdr = CreateRowHeader(kl, (data == null?0:data.Length)); if (deleted) { hdr[(int)HDR_POS.Flags] = (byte)1; } // write header info _writefile.Write(hdr, 0, hdr.Length); // write key _writefile.Write(k, 0, kl); if (data != null) { // write data block _writefile.Write(data, 0, data.Length); if (Global.FlushStorageFileImmetiatley) { _writefile.Flush(); } _lastWriteOffset += data.Length; } // update pointer _lastWriteOffset += hdr.Length; _lastWriteOffset += kl; // return starting offset -> recno int recno = _lastRecordNum++; _recordfile.Write(Helper.GetBytes(offset, false), 0, 8); if (Global.FlushStorageFileImmetiatley) { _recordfile.Flush(); } _flushNeeded = true; return(recno); }
internal void SavePage(Page <T> node) { lock (_fileLock) { int pnum = node.DiskPageNumber; if (pnum > _LastPageNumber) { throw new Exception("should not be here: page out of bounds"); } SeekPage(pnum); byte[] page = new byte[_PageLength]; byte[] blockheader = CreateBlockHeader(0, (ushort)node.tree.Count(), node.RightPageNumber); Buffer.BlockCopy(blockheader, 0, page, 0, blockheader.Length); int index = blockheader.Length; int i = 0; byte[] b = null; T[] keys = node.tree.Keys(); Array.Sort(keys); // sort keys on save for read performance int blocknum = 0; if (_externalStrings) { // free old blocks if (node.allocblocks != null) { _strings.FreeBlocks(node.allocblocks); } blocknum = _strings.SaveData(node.DiskPageNumber.ToString(), BJSON.ToBJSON(keys, new BJSONParameters { UseUnicodeStrings = false, UseTypedArrays = false })); } // node children foreach (var kp in keys) { var val = node.tree[kp]; int idx = index + _rowSize * i; // key bytes byte[] kk; byte size; if (_externalStrings == false) { kk = _T.GetBytes(kp); size = (byte)kk.Length; if (size > _maxKeySize) { size = _maxKeySize; } } else { kk = new byte[4]; Buffer.BlockCopy(Helper.GetBytes(blocknum, false), 0, kk, 0, 4); size = 4; } // key size = 1 byte page[idx] = size; Buffer.BlockCopy(kk, 0, page, idx + 1, page[idx]); // offset = 4 bytes b = Helper.GetBytes(val.RecordNumber, false); Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize, b.Length); // duplicatepage = 4 bytes b = Helper.GetBytes(val.DuplicateBitmapNumber, false); Buffer.BlockCopy(b, 0, page, idx + 1 + _maxKeySize + 4, b.Length); i++; } _file.Write(page, 0, page.Length); } }