/// <summary> /// Adds a new block at he end of the existing sequence of overflow blocks /// </summary> /// <param name="data"></param> /// <param name="block"></param> /// <param name="blockInfo"></param> private void AddNewOverflowBlock(ref T data, ref Block <T> block, ref OverflowBlockInfo blockInfo) { var address = GetFreeAddress(); block.ValidCount = 0; block.AddRecord(data); WriteBytes(address, block.ToByteArray()); blockInfo.NextOwerflowAddress = address; _blocksInfoTable.Add(address, new OverflowBlockInfo()); }
public override void FromByteArray(byte[] array) { using (var ms = new MemoryStream(array)) { var buffer = new byte[sizeof(int)]; ms.Read(buffer); var infoCount = BitConverter.ToInt32(buffer); if (infoCount > 0) { OverflowBlockInfo info; for (int i = 0; i < infoCount; i++) { //kluc ms.Read(buffer); var key = BitConverter.ToInt32(buffer); //info info = new OverflowBlockInfo(); buffer = new byte[info.GetSize()]; ms.Read(buffer); info.FromByteArray(buffer); _blocksInfoTable.Add(key, info); buffer = new byte[sizeof(int)]; } } ms.Read(buffer); var fileManagerAddresses = BitConverter.ToInt32(buffer); if (fileManagerAddresses > 0) { buffer = new byte[sizeof(int) * fileManagerAddresses]; base.FromByteArray(buffer); } } }
public void GetBlockAndInfo(int address, out Block <T> block, out OverflowBlockInfo blockInfo) { block = new Block <T>(_bFactor, _emptyClass); ReadBlock(address, ref block); blockInfo = _blocksInfoTable[address].Value; }
internal void Remove(ref T data, ref BlockInfo blockInfo) { var block = new Block <T>(_bFactor, _emptyClass); // aktualizovat blockInfo ak sa vyprazdnil blok na ktory ukazuje var address = blockInfo.OverflowAddress; OverflowBlockInfo beforeInfo = null; var canContinue = true; while (canContinue) { ReadBlock(address, ref block); var info = _blocksInfoTable[address].Value; if (block.DeleteRecord(data) == null) { if (info.NextOwerflowAddress != int.MinValue) { beforeInfo = info; address = info.NextOwerflowAddress; } else { // zaznam nebol najdeny canContinue = false; } } else { --info.Records; if (info.Records == 0) { // blok ostal prazdny tak prenastavime povodnemu bloku novu adresu zretazenia // odstranime už nepotrebnu informaciu // uvolnime adresu if (beforeInfo != null) { beforeInfo.NextOwerflowAddress = info.NextOwerflowAddress; } else { blockInfo.OverflowAddress = info.NextOwerflowAddress; } _blocksInfoTable.Remove(address); FreeAddress(address); } else { if (!TryShake(blockInfo.OverflowAddress, address, ref block, out var newOverflowAddress)) { WriteBytes(address, block.ToByteArray()); } else { if (newOverflowAddress >= 0) { blockInfo.OverflowAddress = newOverflowAddress; } } } canContinue = false; } } }