예제 #1
0
        /// <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);
        }
예제 #2
0
        /// <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;
                }
            }
        }
예제 #3
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);
 }
예제 #4
0
 /// <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);
 }