Exemplo n.º 1
0
 /// <summary>
 /// protected virtual dispose.
 /// Closes this Collection on disk, its deleted blocks and Mru Segments.
 /// Sets the data block driver to null.
 /// </summary>
 protected internal virtual void InternalDispose()
 {
     if (FileStream != null)
     {
         Close();
     }
     if (deletedBlocks != null)
     {
         deletedBlocks.Dispose();
         deletedBlocks = null;
     }
     Parent = null;
     if (DataBlockDriver != null)
     {
         if (!IsCloned)
         {
             DataBlockDriver.Dispose();
         }
         DataBlockDriver = null;
     }
     if (OnDiskBinaryReader != null)
     {
         OnDiskBinaryReader.Close();
         OnDiskBinaryReader = null;
     }
     if (OnDiskBinaryWriter != null)
     {
         OnDiskBinaryWriter.Close();
         OnDiskBinaryWriter = null;
     }
     _instanceTransaction     = null;
     _parentTransactionLogger = null;
     File = null;
 }
Exemplo n.º 2
0
        /// <summary>
        /// Serialize this Collection meta info
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="writer"></param>
        public virtual void Pack(IInternalPersistent parent, System.IO.BinaryWriter writer)
        {
            writer.Write(DataAddress);
            writer.Write((int)DataBlockSize);
            writer.Write(Name);
            writer.Write(HintSizeOnDisk);
            if (DataBlockDriver == null)
            {
                writer.Write(DiskBuffer.DataAddress);
            }
            else
            {
                writer.Write(DataBlockDriver.GetId(this.DiskBuffer));
            }
            bool hasHeader = HeaderData != null;

            writer.Write(hasHeader);
            if (hasHeader)
            {
                HeaderData.Pack(parent, writer);
            }

            bool hasDeletedBlocks = deletedBlocks != null;

            writer.Write(hasDeletedBlocks);
            if (hasDeletedBlocks)
            {
                writer.Write(deletedBlocks.DiskBuffer.DataAddress);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Shallow copy the Collection into a new instance and return it.
        /// </summary>
        public virtual object Clone()
        {
            var lid = new LinkedListOnDisk
            {
                File            = File,
                DataBlockSize   = DataBlockSize,
                HintSizeOnDisk  = HintSizeOnDisk,
                currentEntry    = currentEntry,
                DataAddress     = DataAddress,
                MruManager      = MruManager,
                MruMinCapacity  = MruMinCapacity,
                MruMaxCapacity  = MruMaxCapacity,
                SyncRoot        = SyncRoot,
                DataBlockDriver = (DataBlock.DataBlockDriver)DataBlockDriver.Clone(),
                FirstItem       = new LinkedItemOnDisk(File.DataBlockSize)
            };

            lid.CurrentItem = lid.FirstItem;
            lid.LastItem    = new LinkedItemOnDisk(File.DataBlockSize);
            int systemDetectedBlockSize;

            lid.FileStream         = File.UnbufferedOpen(out systemDetectedBlockSize);
            lid.isOpen             = true;
            lid.IsCloned           = true;
            lid.Name               = Name; // string.Format("{0} Clone", Name);
            lid.OnDiskBinaryWriter = new OnDiskBinaryWriter(File.Server.Encoding);
            lid.OnDiskBinaryReader = new OnDiskBinaryReader(File.Server.Encoding);
            return(lid);
        }
Exemplo n.º 4
0
 /// <summary>
 /// Returns flag that tells whether this Collection had been modified or not
 /// </summary>
 /// <param name="block"></param>
 /// <returns></returns>
 public bool GetIsDirty(Sop.DataBlock block)
 {
     if (DataBlockDriver == null)
     {
         return(block.IsDirty);
     }
     return(DataBlockDriver.GetIsDirty(block));
 }
Exemplo n.º 5
0
 /// <summary>
 /// Returns the Current Sop.DataBlock with option not to put it on cache
 /// </summary>
 /// <param name="getForRemoval"></param>
 /// <returns></returns>
 protected internal Sop.DataBlock GetCurrentDataBlock(bool getForRemoval)
 {
     if (currentDataBlock == null || DataBlockDriver.GetId(currentDataBlock) == -1)
     {
         currentDataBlock = DataBlockDriver.ReadBlockFromDisk(this, getForRemoval);
     }
     return(currentDataBlock);
 }
Exemplo n.º 6
0
        /// <summary>
        /// Clear contents of this Collection.
        /// Changes will be saved right after clearing the contents.
        /// </summary>
        public virtual void Clear()
        {
            if (HeaderData.OccupiedBlocksHead != null && HeaderData.OccupiedBlocksTail != null)
            {
                HeaderData.DiskBuffer.IsDirty              = true;
                HeaderData.OccupiedBlocksTail.DataAddress  =
                    HeaderData.NextAllocatableAddress      =
                        HeaderData.StartAllocatableAddress = HeaderData.OccupiedBlocksHead.DataAddress;

                int segmentSize = File.GetSegmentSize();
                if (HeaderData.OccupiedBlocksHead.DataAddress + segmentSize != HeaderData.EndAllocatableAddress)
                {
                    //**** add to File.DeletedCollections the next _region for reuse...
                    //** read next segment of deleted collection
                    var           dbi = new DeletedBlockInfo();
                    Sop.DataBlock db;
                    db = DataBlockDriver.ReadBlockFromDisk(this,
                                                           HeaderData.OccupiedBlocksHead.DataAddress + segmentSize -
                                                           (int)File.DataBlockSize, true);
                    if (db.InternalNextBlockAddress >= 0)
                    {
                        dbi.StartBlockAddress = db.InternalNextBlockAddress;
                        dbi.EndBlockAddress   = db.InternalNextBlockAddress + segmentSize;

                        if (File.DeletedCollections != null)
                        {
                            bool oc = ((CollectionOnDisk)File.DeletedCollections).ChangeRegistry;
                            ((CollectionOnDisk)File.DeletedCollections).ChangeRegistry = ChangeRegistry;
                            File.DeletedCollections.Add(dbi);
                            ((CollectionOnDisk)File.DeletedCollections).ChangeRegistry = oc;
                        }

                        HeaderData.EndAllocatableAddress = HeaderData.OccupiedBlocksHead.DataAddress + segmentSize;
                    }
                }
            }
            HeaderData.Count = 0;
            if (HeaderData.diskBuffer != null)
            {
                HeaderData.diskBuffer.ClearData();
            }
            if (deletedBlocks != null)
            {
                deletedBlocks.Clear();
            }
            //if (MruManager != null)
            //    MruManager.Clear();
            //if (this.DataBlockDriver != null)
            //    this.DataBlockDriver.MruManager.Clear();
            //Blocks.Clear();
            currentDataBlock         = null;
            currentEntry             = null;
            _currentEntryDataAddress = -1;
            RegisterChange();
            Flush();
        }
Exemplo n.º 7
0
 /// <summary>
 /// Mark this Collection as modified or not
 /// </summary>
 /// <param name="block"></param>
 /// <param name="newValue"></param>
 public void SetIsDirty(Sop.DataBlock block, bool newValue)
 {
     if (DataBlockDriver == null)
     {
         block.IsDirty = newValue;
     }
     else
     {
         DataBlockDriver.SetIsDirty(block, newValue);
     }
 }
Exemplo n.º 8
0
 /// <summary>
 /// Remove ObjectToRemove from the Collection if found, else throws an exception
 /// </summary>
 public void Remove(object item)
 {
     if (!Contains(item))
     {
         return;
     }
     Sop.DataBlock currBlock = this.GetCurrentDataBlock(true);
     if (GetId(currBlock) >= 0)
     {
         MruManager.Remove(GetId(currBlock), true);
     }
     DataBlockDriver.Remove(this, currBlock);
 }
Exemplo n.º 9
0
        /// <summary>
        /// Add 'Value' to the Collection
        /// </summary>
        public long Add(object value)
        {
            var o = new LinkedItemOnDisk(this.DataBlockSize)
            {
                Data = value
            };

            WriteToDisk(o, false);
            UpdateCount(UpdateCountType.Increment);
            //*** update Current, Last & First
            if (LastItem.DiskBuffer.DataAddress != -1)
            {
                o.PreviousItemAddress = LastItem.DiskBuffer.DataAddress;
                WriteToDisk(o, false);
                LinkedItemOnDisk biod = CurrentItem;
                biod.NextItemAddress = o.DiskBuffer.DataAddress;
                Sop.DataBlock db = DataBlockDriver.ReadBlockFromDisk(this, LastItem.DiskBuffer.DataAddress, true);
                if (CurrentItem.DiskBuffer.DataAddress != LastItem.DiskBuffer.DataAddress)
                {
                    biod = (LinkedItemOnDisk)ReadFromBlock(db);
                    biod.NextItemAddress = o.DiskBuffer.DataAddress;
                }
                else
                {
                    PurifyMeta(biod, db);
                    if (db.SizeOccupied > 0)
                    {
                        biod.DiskBuffer = db;
                    }
                }
                WriteToDisk(biod, false);
            }
            else
            {
                FirstItem.DiskBuffer.DataAddress = o.DiskBuffer.DataAddress;
            }

            currentEntry                    = null;
            CurrentItem                     = o;
            CurrentEntryDataAddress         = o.DiskBuffer.DataAddress;
            currentDataBlock                = o.DiskBuffer;
            LastItem.DiskBuffer.DataAddress = o.DiskBuffer.DataAddress;

            MruManager.Add(CurrentEntryDataAddress, o);

            //** update the header
            RegisterChange(true);
            //IsDirty = true;

            return(o.DiskBuffer.DataAddress);
        }
Exemplo n.º 10
0
        /// <summary>
        /// protected virtual dispose.
        /// Closes this Collection on disk, its deleted blocks and Mru Segments.
        /// Sets the data block driver to null.
        /// </summary>
        protected internal virtual void InternalDispose()
        {
            // note: SOP's Dispose pattern is created to provide way to do early
            // garbage collection of the "graph" objects, simply. Not for freeing up unmanaged
            // resources, thus, no finalizer/SafeHandle "patterns". All members are "virtualized"
            // objects and they have custom Dispose for the same.
            if (isDisposed)
            {
                return;
            }
            isDisposed = true;
            // FileStream is a wrapper, not the .Net FileStream.
            if (FileStream != null)
            {
                Close();
            }
            if (deletedBlocks != null)
            {
                deletedBlocks.Dispose();
                deletedBlocks = null;
            }
            Parent = null;
            if (DataBlockDriver != null)
            {
                //if (!IsCloned)
                DataBlockDriver.Dispose();
                DataBlockDriver = null;
            }
            if (OnDiskBinaryReader != null)
            {
                OnDiskBinaryReader.Close();
                OnDiskBinaryReader = null;
            }
            if (OnDiskBinaryWriter != null)
            {
                OnDiskBinaryWriter.Close();
                OnDiskBinaryWriter = null;
            }
            _instanceTransaction     = null;
            _parentTransactionLogger = null;
            File   = null;
            Blocks = null;
            var locker = _syncRoot as IDisposable;

            if (locker != null)
            {
                locker.Dispose();
            }
        }
Exemplo n.º 11
0
 /// <summary>
 /// Delete & Dispose this collection.
 /// Send all allocated segments:blocks to recycle bin
 /// </summary>
 public virtual void Delete()
 {
     if (DataBlockDriver != null)
     {
         DataBlockDriver.Delete(this);
         CollectionOnDisk codParent = GetTopParent();
         if (codParent.deletedBlocks != null &&
             codParent.deletedBlocks.DataAddress >= 0)
         {
             IDataBlockRecycler dc = codParent.deletedBlocks;
             codParent.deletedBlocks = null;
             dc.Delete();
         }
     }
     Dispose();
 }
Exemplo n.º 12
0
        /// <summary>
        /// Reads into memory the Collection On Disk's Header Block which contains
        /// state information of the collection
        /// </summary>
        public virtual void Load()
        {
            if (DiskBuffer == null)
            {
                throw new InvalidOperationException("'DiskBuffer' is null.");
            }
            if (DataBlockDriver.GetId(DiskBuffer) < 0)
            {
                throw new InvalidOperationException("'DiskBuffer.DataAddress' is < 0.");
            }

            //Blocks.Clear();
            //if (DataBlockDriver.MruManager != null)
            //    DataBlockDriver.MruManager.Clear();
            //if (MruManager != null)
            //    MruManager.Clear();

            currentDataBlock = null;
            DataBlockDriver.MoveTo(this, DataBlockDriver.GetId(DiskBuffer));

            Sop.DataBlock block = GetCurrentDataBlock();

            if (block.SizeOccupied > 0)
            {
                if (block.DataAddress == DiskBuffer.DataAddress &&
                    DiskBuffer.Data == null)
                {
                    DiskBuffer = block;
                }
                ReadFromBlock(block, this);
                DiskBuffer = block;
            }
            if (IsDirty)
            {
                IsDirty = false;
            }

            //** allow deleted blocks to be loaded its Header and clear its MRU cache...
            if (File.Server.HasTrashBin && _deletedBlocksAddress >= 0) // && deletedBlocks.DataAddress >= 0)
            {
                // ensure Deleted Blocks collection is loaded & initialized.
                var o = DeletedBlocks;
                //if (DeletedBlocksAddress != DeletedBlocks.DataAddress)
                //    DeletedBlocks.DataAddress = DeletedBlocksAddress;
                deletedBlocks.Load();
            }
        }
Exemplo n.º 13
0
 /// <summary>
 /// MoveFirst makes the first entry in the Collection the current one
 /// </summary>
 public override bool MoveFirst()
 {
     if (Count > 0 && CurrentItem != null)
     {
         if (FirstItem.DiskBuffer.DataAddress != CurrentEntryDataAddress ||
             FirstItem.DiskBuffer.DataAddress != CurrentItem.DiskBuffer.DataAddress)
         {
             CurrentEntryDataAddress = -1;
             this.DataBlockDriver.MoveTo(this, FirstItem.DiskBuffer.DataAddress);
             Sop.DataBlock db = DataBlockDriver.ReadBlockFromDisk(this, FirstItem.DiskBuffer.DataAddress, false);
             this.currentDataBlock = db;
             CurrentItem           = (LinkedItemOnDisk)ReadFromBlock(db);
         }
         return(true);
     }
     return(false);
 }
Exemplo n.º 14
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);
        }
Exemplo n.º 15
0
        /// <summary>
        /// DeSerialize this Collection's Meta Info
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="reader"></param>
        public virtual void Unpack(IInternalPersistent parent, System.IO.BinaryReader reader)
        {
            long da = reader.ReadInt64();

            if (da >= 0)
            {
                DataAddress = da;
            }
            DataBlockSize  = (DataBlockSize)reader.ReadInt32();
            Name           = reader.ReadString();
            HintSizeOnDisk = reader.ReadInt32();
            long l = reader.ReadInt64();

            if (l >= 0)
            {
                DataBlockDriver.SetId(this.DiskBuffer, l);
            }
            bool hasHeader = reader.ReadBoolean();

            if (hasHeader)
            {
                if (HeaderData == null)
                {
                    HeaderData = new HeaderData();
                }
                HeaderData.Unpack(parent, reader);
            }

            MruMinCapacity = ((CollectionOnDisk)parent).File.Profile.MruMinCapacity;
            MruMaxCapacity = ((CollectionOnDisk)parent).File.Profile.MruMaxCapacity;

            bool hasDeletedBlocks = reader.ReadBoolean();

            if (hasDeletedBlocks)
            {
                _deletedBlocksAddress = reader.ReadInt64();
            }
            else if (deletedBlocks != null)
            {
                deletedBlocks = null;
            }
        }
Exemplo n.º 16
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;
                }
            }
        }
Exemplo n.º 17
0
 protected virtual void WriteBlocksToDisk(ICollectionOnDisk parent,
                                          IDictionary <long, Sop.DataBlock> blocks, bool clear)
 {
     DataBlockDriver.WriteBlocksToDisk(parent, blocks, clear);
 }
Exemplo n.º 18
0
        /// <summary>
        /// Initialize. NOTE: this function doesn't open the file.
        /// </summary>
        /// <param name="file"></param>
        /// <param name="parameters"> </param>
        protected internal virtual void Initialize(File.IFile file, params KeyValuePair <string, object>[] parameters)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            if (transaction == null ||
                (transaction is Transaction.Transaction &&
                 ((Transaction.Transaction)transaction).Server != file.Server))
            {
                Transaction.ITransactionLogger trans = file.Transaction;
                if (trans != null)
                {
                    trans = ((Transaction.TransactionBase)trans).GetLeafChild();
                }
                if (trans == null ||
                    trans is Transaction.Transaction)
                {
                    transaction = trans;
                }
            }

            if (string.IsNullOrEmpty(this.Name))
            {
                var f = new FileInfo(file.Filename);
                Name = string.Format("{0} Collection {1}", f.Name, ((Sop.OnDisk.File.File)file).GetNewStoreId());
            }
            if (MruMinCapacity == 0)
            {
                MruMinCapacity = file.Profile.MruMinCapacity;
            }
            if (MruMaxCapacity == 0)
            {
                MruMaxCapacity = file.Profile.MruMaxCapacity;
            }

            if (File == null)
            {
                File = file;
            }
            if (DataBlockSize == DataBlockSize.Unknown)
            {
                DataBlockSize = file.DataBlockSize;
            }
            HeaderData hd = null;

            if (parameters != null && parameters.Length > 0)
            {
                foreach (KeyValuePair <string, object> o in parameters)
                {
                    switch (o.Key)
                    {
                    case "HasMruSegments":
                        break;

                    case "HeaderData":
                        hd = (HeaderData)o.Value;
                        break;

                    default:
                        if (o.Key == "DataBlockDriver" && o.Value != null)
                        {
                            DataBlockDriver = (IDataBlockDriver)o.Value;
                        }
                        break;
                    }
                }
            }
            if (DataBlockDriver == null)
            {
                DataBlockDriver = new DataBlockDriver(this, hd);
            }
            else
            {
                if (DataBlockDriver.HeaderData == null)
                {
                    DataBlockDriver.HeaderData = hd ?? new HeaderData(DataBlockSize);
                }
            }
            if (MruManager == null)
            {
                int min = MruMinCapacity;
                int max = MruMaxCapacity;

                //MruManager = new ConcurrentMruManager(min, max);
                MruManager = new MruManager(min, max);

                MruManager.SetDataStores(this, DataBlockDriver);
            }
            if (_diskBuffer == null)
            {
                _diskBuffer = CreateBlock(); //new Sop.DataBlock(DataBlockSize);
            }
        }
Exemplo n.º 19
0
 /// <summary>
 /// OnRead gets called to read Object from Disk
 /// </summary>
 /// <param name="address">Address of Object on disk</param>
 /// <returns></returns>
 protected internal virtual object OnRead(long address)
 {
     //** read Node including Keys
     Sop.DataBlock d = DataBlockDriver.ReadBlockFromDisk(this, address, false);
     return(ReadFromBlock(d));
 }
Exemplo n.º 20
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);
 }
Exemplo n.º 21
0
        /// <summary>
        /// Open the Collection
        /// </summary>
        public virtual void Open()
        {
            SetupCachePool();

            if (DataBlockDriver == null)
            {
                throw new InvalidOperationException(
                          "DataBlockDriver is null. Make sure you have assigned valid File 'Parent'"
                          );
            }
            if (OnDiskBinaryWriter == null && File.Server != null)
            {
                OnDiskBinaryWriter = new OnDiskBinaryWriter(File.Server.Encoding);
                OnDiskBinaryReader = new OnDiskBinaryReader(File.Server.Encoding);
            }
            if (isOpen)
            {
                return;
            }
            long fileSize = 0;

            if (FileStream == null)
            {
                int systemDetectedBlockSize;
                FileStream = File.UnbufferedOpen(out systemDetectedBlockSize);
                if (FileStream != null &&
                    File.Size < (fileSize = FileStream.Length))
                {
                    short ss           = (short)DataBlockSize;
                    long  segmentSize  = File.CollectionGrowthSizeInNob * ss;
                    long  segmentCount = fileSize / segmentSize;
                    if (fileSize % segmentSize != 0 || segmentCount == 0)
                    {
                        segmentCount++;
                    }
                    File.Size = segmentCount * segmentSize;
                }
            }
            isOpen = true;
            //** read the header if there is one...
            if (DiskBuffer == null)
            {
                return;
            }
            if (fileSize == 0)
            {
                fileSize = FileStream.Length;
            }
            if (DataBlockDriver.GetId(DiskBuffer) >= 0 && fileSize > 0)
            {
                if (deletedBlocks != null)
                {
                    deletedBlocks.Open();
                }
                Load();
                ReuseCacheFromPool();
                IsDirty = false;
            }
            else
            {
                //** write header into 1st block
                if (fileSize == 0 && File.Store.IsItMe(this))
                {
                    bool shouldGenerateZeroAddress = false;
                    if (File.Server != null)
                    {
                        if (DiskBuffer.DataAddress == File.DiskBuffer.DataAddress)
                        {
                            DiskBuffer.DataAddress    = -1;
                            shouldGenerateZeroAddress = true;
                        }
                        Flush();
                        IsDirty = DataAddress == -1;
                    }
                    if (shouldGenerateZeroAddress && DiskBuffer.DataAddress != 0)
                    {
                        throw new InvalidOperationException(
                                  "Didn't allocate the 1st block(DataAddress=0) on collection's DiskBuffer.");
                    }
                }
            }
        }
Exemplo n.º 22
0
 /// <summary>
 /// Set Block ID to a given Address
 /// </summary>
 /// <param name="block"></param>
 /// <param name="address"></param>
 public void SetId(Sop.DataBlock block, long address)
 {
     DataBlockDriver.SetId(block, address);
 }
Exemplo n.º 23
0
 /// <summary>
 /// Returns the ID(DataAddress if block is not virtualized block) of a given block
 /// </summary>
 /// <param name="block"></param>
 /// <returns></returns>
 public long GetId(Sop.DataBlock block)
 {
     return(DataBlockDriver.GetId(block));
 }
Exemplo n.º 24
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);
 }
Exemplo n.º 25
0
        //private const int ObjectBlockCountThreshold = 64;
        /// <summary>
        /// If in AutoFlush mode and data Value is not saved in Key segment,
        /// this method will Add/Update Big Data Value to disk and at end of the process,
        /// set the Value to null to conserve memory.
        /// </summary>
        /// <param name="item"></param>
        /// <returns></returns>
        private bool SetBigDataValue(BTreeItemOnDisk item)
        {
            if (!IsDataInKeySegment)
            {
                // load meta data so Blocks layout in-memory can get recreated...
                long da = GetId(item.Value.DiskBuffer);
                if (da >= 0)
                {
                    if (!item.Value.DiskBuffer.IsFolded)
                    {
                        if (item.Value.DiskBuffer.IsFoldedInfoOnDisk)
                        {
                            // read the block chain info so these blocks will not be replaced during update!
                            var metaBlocks = DataBlockDriver.ReadBlockInfoFromDisk(this, da);
                            // assign read block chain info to a DataBlock simulating a "Folded" scenario.
                            item.Value.diskBuffer.foldedDataAddresses  = metaBlocks.ToArray();
                            item.Value.diskBuffer.contiguousBlockCount = metaBlocks[0].BlockCount;
                        }
                    }
                    // delete the blocks on disk if they are big and data being set is null
                    if (item.Value.Data == null &&
                        item.Value.DiskBuffer.IsFolded &&
                        item.Value.DiskBuffer.CountMembers() >= 1024)
                    {
                        DataSet.DataBlockDriver.Remove(DataSet, item.Value.DiskBuffer);
                        item.Value.DiskBuffer = CreateBlock();
                    }
                }

                // save big data to disk
                if (item.Value.diskBuffer != null)
                {
                    item.Value.diskBuffer.Unfold(this);
                }
                Sop.DataBlock b = WriteToBlock(item.Value);
                DataSet.DataBlockDriver.SetDiskBlock(DataSet, b, false, false);
                var cnt = b.ProcessHeadSets();

                // store blocks to the pool if block count < 500, otherwise direct write to disk!
                if (cnt < File.Profile.BigDataBlockCount)
                {
                    AddToBlocks(b, Blocks);
                    item.ValueLoaded   = true;
                    item.Value.IsDirty = false;
                    item.IsDirty       = false;
                    item.Value.diskBuffer.Fold();
                }
                else
                {
                    if (cnt <= 500)
                    {
                        AddToBlocks(b, Blocks);
                    }
                    else
                    {
                        // direct write to disk
                        var blocks = new Collections.Generic.SortedDictionary <long, Sop.DataBlock>();
                        AddToBlocks(b, blocks);
                        WriteBlocksToDisk(DataSet, blocks, false);
                    }
                    item.IsDirty       = false;
                    item.Value.IsDirty = false;
                    item.ValueLoaded   = false;
                    item.Value.diskBuffer.Fold();
                    // nullify big data to conserve memory
                    item.Value.Data = null;
                }
                return(true);
            }
            return(false);
        }
Exemplo n.º 26
0
 internal Sop.DataBlock CreateBlock(DataBlockSize size)
 {
     return(DataBlockDriver.CreateBlock(size));
 }