예제 #1
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);
            }
        }
예제 #2
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);
 }
예제 #3
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();
            }
        }
예제 #4
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;
                }
            }
        }
예제 #5
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.");
                    }
                }
            }
        }
예제 #6
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));
 }