/// <summary> /// When maximum capacity of Collection's Objects' MRU Manager is reached, /// it calls this version of "OnMaxCapacity" in order to /// reduce the number of objects kept in-memory /// </summary> /// <param name="nodes">List of Collection Objects or "Nodes" that were removed /// from memory and should be saved to disk</param> public virtual int OnMaxCapacity(IEnumerable nodes) { foreach (IInternalPersistent node in nodes) { if (!node.IsDirty) { continue; } //** save Items' Data var block = WriteToBlock(node); DataBlockDriver.SetDiskBlock(this, block, false); AddToBlocks(block, Blocks); node.IsDirty = false; } int r = Blocks.Count; SaveBlocks(false); return(r); }
/// <summary> /// Register current collection's state /// </summary> public virtual void RegisterChange(bool partialRegister = false) { IsDirty = true; _registerCallCount++; if (_registerCallCount == 1) { if (DiskBuffer == null) { throw new InvalidOperationException("'DiskBuffer' is null."); } bool stateSerialized = false; if (!partialRegister || DiskBuffer.SizeOccupied == 0) { stateSerialized = true; DiskBuffer.ClearData(); OnDiskBinaryWriter.WriteObject(File, this, DiskBuffer); } if (!ChangeRegistry) { _registerCallCount = 0; if (!partialRegister || stateSerialized) { Blocks.Add(DataBlockDriver.GetId(DiskBuffer), DiskBuffer); //90; } //DataBlockDriver.MruManager.Add(DataBlockDriver.GetId(DiskBuffer), DiskBuffer); } else { DataBlockDriver.SetDiskBlock(this, DiskBuffer, true); if (_registerCallCount > 1) { _registerCallCount = 0; //IsDirty = true; RegisterChange(partialRegister); } _registerCallCount = 0; } } }
//internal override bool RemoveInMemory(long DataAddress, Transaction.ITransactionLogger Transaction) //{ // if (LastItem != null) // LastItem.Clear(); // if (FirstItem != null) // FirstItem.Clear(); // CurrentItem = null; // base.RemoveInMemory(DataAddress, Transaction); // return true; //} private void RemoveAt(long dataAddress, bool willMove) { if (willMove && !MoveTo(dataAddress)) { return; } if (IsDeletedBlocksList && Count == 1) { return; } Sop.DataBlock currBlock = this.GetCurrentDataBlock(true); if (FirstItem.DiskBuffer.DataAddress == dataAddress) { MoveFirst(); if (MoveNext()) { FirstItem.DiskBuffer.DataAddress = CurrentItem.DiskBuffer.DataAddress; CurrentItem.PreviousItemAddress = -1; Sop.DataBlock db = WriteToBlock(CurrentItem, CurrentItem.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); } else { long address = FirstItem.DiskBuffer.DataAddress; FirstItem.DiskBuffer.DataAddress = LastItem.DiskBuffer.DataAddress = -1; CurrentItem = FirstItem; Sop.DataBlock db = WriteToBlock(CurrentItem, CurrentItem.DiskBuffer); db.DataAddress = address; DataBlockDriver.SetDiskBlock(this, db, false); db.DataAddress = -1; } } else if (LastItem.DiskBuffer.DataAddress == dataAddress) { if (MovePrevious() || FirstItem.DiskBuffer.DataAddress == CurrentItem.DiskBuffer.DataAddress) { LastItem.DiskBuffer.DataAddress = CurrentItem.DiskBuffer.DataAddress; CurrentItem.NextItemAddress = -1; Sop.DataBlock db = WriteToBlock(CurrentItem, CurrentItem.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); } else { throw new InvalidOperationException("Can't go previous but First is not the only item."); } } else { LinkedItemOnDisk curr = CurrentItem; LinkedItemOnDisk prev = null, next = null; if (MoveTo(curr.PreviousItemAddress)) { prev = CurrentItem; } if (MoveTo(curr.NextItemAddress)) { next = CurrentItem; } if (prev != null && next != null) { prev.NextItemAddress = curr.NextItemAddress; next.PreviousItemAddress = curr.PreviousItemAddress; Sop.DataBlock db = WriteToBlock(prev, prev.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); db = WriteToBlock(next, next.DiskBuffer); DataBlockDriver.SetDiskBlock(this, db, false); } } if (MruManager.Count > 0) { MruManager.Remove(dataAddress, true); } DataBlockDriver.Remove(this, currBlock); }
/// <summary> /// Serialize object and write its byte array to disk /// </summary> /// <param name="value"></param> /// <param name="isCollectionBlock"> </param> protected void WriteToDisk(IInternalPersistent value, bool isCollectionBlock) { Sop.DataBlock block = WriteToBlock(value, value.DiskBuffer); DataBlockDriver.SetDiskBlock(this, block, isCollectionBlock); }