예제 #1
0
        internal static int SizeOfMetaData(IInternalPersistent parent)
        {
            if (parent == null)
            {
                throw new ArgumentNullException("parent");
            }
            if (!(parent is CollectionOnDisk))
            {
                throw new ArgumentException("Parent is not CollectionOnDisk type.");
            }

            if (Encoding != ((CollectionOnDisk)parent).File.Server.Encoding)
            {
                Encoding = ((CollectionOnDisk)parent).File.Server.Encoding;
                _sizeOf  = 0;
            }
            if (_sizeOf == 0)
            {
                var o = new LinkedItemOnDisk
                {
                    DiskBuffer = ((CollectionOnDisk)parent).DataBlockDriver.
                                 CreateBlock(((CollectionOnDisk)parent).File.DataBlockSize),
                    Data = new byte[0]
                };
                var w = new OnDiskBinaryWriter(Encoding)
                {
                    DataBlock = o.DiskBuffer
                };
                WritePersistentData(parent, o, w);
                _sizeOf = (int)w.BaseStream.Position;
                w.Close();
            }
            return(_sizeOf);
        }
예제 #2
0
        /// <summary>
        /// Write Value to the Sop.DataBlock
        /// </summary>
        protected internal Sop.DataBlock WriteToBlock(object value)
        {
            if (!(value is IInternalPersistent))
            {
                var db = CreateBlock();
                return(WriteToBlock(value, db, false));
            }
            int sizeOnDisk = ((IInternalPersistent)value).HintSizeOnDisk;

            if (sizeOnDisk == 0 && this is BTreeAlgorithm)
            {
                sizeOnDisk = ((BTreeAlgorithm)this).HintValueSizeOnDisk;
            }
            if (((IInternalPersistent)value).DiskBuffer == null)
            {
                ((IInternalPersistent)value).DiskBuffer        = CreateBlock();
                ((IInternalPersistent)value).DiskBuffer.IsHead = true;
            }
            else
            {
                ((IInternalPersistent)value).DiskBuffer.ClearData();
            }
            Sop.DataBlock r = WriteToBlock(value, ((IInternalPersistent)value).DiskBuffer);
            int           sizeWrittenOnStream = r.GetSizeOccupied();

            if (sizeOnDisk > sizeWrittenOnStream)
            {
                var b = new byte[sizeOnDisk - sizeWrittenOnStream];
                OnDiskBinaryWriter.Write(b);
            }
            return(r);
        }
예제 #3
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;
 }
예제 #4
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();
            }
        }
예제 #5
0
        public override void Close()
        {
            if (!IsOpen)
            {
                return;
            }
            base.Close();
            if (OnDiskBinaryWriter != null)
            {
                OnDiskBinaryWriter.Close();
                OnDiskBinaryWriter = null;
            }
            if (OnDiskBinaryReader != null)
            {
                OnDiskBinaryReader.Close();
                OnDiskBinaryReader = null;
            }

            FirstItem        = new LinkedItemOnDisk(File.DataBlockSize);
            this.CurrentItem = FirstItem;
            LastItem         = new LinkedItemOnDisk(File.DataBlockSize);
        }
예제 #6
0
        /// <summary>
        /// Close the Collection
        /// </summary>
        public virtual void Close()
        {
            bool miscCollsClosed = false;

            if (IsOpen)
            {
                if (!IsCloned)
                {
                    OnCommit();
                }
                if (IsDirty && !IsCloned && DataAddress >= 0 && Count > 0)
                {
                    Flush();
                }
                if (deletedBlocks != null)
                {
                    deletedBlocks.Close();
                }
                miscCollsClosed = true;
                if (DataBlockDriver != null)
                {
                    if (!IsCloned)
                    {
                        //DataBlocksPool.RemoveFromPool(this.DataBlockDriver.MruManager);
                        //this.DataBlockDriver.MruManager.Clear();
                        DataBlockDriver.HeaderData.Clear();
                    }
                }
                if (Parent == null)
                {
                    if (OnDiskBinaryWriter != null)
                    {
                        OnDiskBinaryWriter.Close();
                        OnDiskBinaryWriter = null;
                    }
                    if (OnDiskBinaryReader != null)
                    {
                        OnDiskBinaryReader.Close();
                        OnDiskBinaryReader = null;
                    }
                }
                if (Blocks != null)
                {
                    Blocks.Clear();
                }
                currentDataBlock         = null;
                currentEntry             = null;
                _currentEntryDataAddress = -1;
                isOpen = false;
            }
            if (_fileStream != null)
            {
                _fileStream.Close();
                _fileStream = null;
            }
            if (!miscCollsClosed)
            {
                if (deletedBlocks != null)
                {
                    deletedBlocks.Close();
                }
            }
            if (_isUnloading)
            {
                _isUnloading = false;
            }
            long da = DiskBuffer.DataAddress;

            DiskBuffer.Initialize();
            DiskBuffer.DataAddress = da;
        }
예제 #7
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.");
                    }
                }
            }
        }