예제 #1
0
        /// <summary>
        /// Delete the Collection for recycling
        /// </summary>
        public void Delete(Algorithm.Collection.ICollectionOnDisk parent)
        {
            if (HeaderData != null && HeaderData.OccupiedBlocksHead != null)
            {
                //** add deleted collection start and end block info to the deleted blocks collection of the File
                var dbi = new DeletedBlockInfo
                {
                    StartBlockAddress = HeaderData.OccupiedBlocksHead.DataAddress,
                    EndBlockAddress   = HeaderData.EndAllocatableAddress
                };
                bool oc = false;
                if (parent.File.DeletedCollections != null)
                {
                    oc = ((Algorithm.BTree.IBTreeAlgorithm)parent.File.DeletedCollections).ChangeRegistry;
                    ((Algorithm.BTree.IBTreeAlgorithm)parent.File.DeletedCollections).ChangeRegistry =
                        ((Algorithm.BTree.IBTreeAlgorithm)parent).ChangeRegistry;
                    parent.File.DeletedCollections.Add(dbi);
                }

                //** Reset count to 0 and save the header to disk
                HeaderData.Count = 0;
                if (!parent.IsTransactionStore)
                {
                    parent.RegisterChange(true);
                }
                if (parent.File.DeletedCollections != null)
                {
                    ((Algorithm.BTree.IBTreeAlgorithm)parent.File.DeletedCollections).ChangeRegistry = oc;
                }
                HeaderData.Clear();
            }
        }
예제 #2
0
        /// <summary>
        /// Remove Block from the Collection
        /// </summary>
        public void Remove(Algorithm.Collection.ICollectionOnDisk parent, Sop.DataBlock block, bool clearBlock = true)
        {
            if (!parent.File.Server.HasTrashBin)
            {
                return;
            }
            //** remove block and linked blocks from MRU
            Sop.DataBlock d = block;
            long          contiguousBlockStartAddress = -1;
            long          currentBlockAddress         = -1;
            int           contiguousBlockCount        = 0;

            var deletedBlocks = ((CollectionOnDisk)parent).DeletedBlocks;
            IDictionary <long, Sop.DataBlock> blocks = ((CollectionOnDisk)parent).Blocks;

            do
            {
                if (d.DataAddress >= 0)
                {
                    blocks.Remove(d.DataAddress);
                }
                if (currentBlockAddress >= 0 && currentBlockAddress + (int)parent.DataBlockSize == d.DataAddress)
                {
                    //** if current block is part of a single contiguous block
                    contiguousBlockCount++;
                    currentBlockAddress = d.DataAddress;
                }
                else
                {
                    if (currentBlockAddress != -1)
                    {
                        //** recycle segment
                        if (deletedBlocks != null)
                        {
                            deletedBlocks.AddAvailableBlock(contiguousBlockStartAddress,
                                                            contiguousBlockCount * (int)parent.DataBlockSize);
                        }
                    }
                    currentBlockAddress         = d.DataAddress;
                    contiguousBlockStartAddress = d.DataAddress;
                    contiguousBlockCount        = 1;
                }

                //** clear block's data
                if (clearBlock && d.SizeOccupied > 0)
                {
                    d.SizeOccupied = 0;
                }

                if (d.Next == null && d.NextItemAddress >= 0)
                {
                    //** load the next datablock to get its next block address...
                    d.Next = ReadBlockFromDisk(parent, parent.FileStream.Position, true, true,
                                               CreateBlock(parent.DataBlockSize));
                }

                d = d.Next;
            } while (d != null);

            //** add to deleted blocks store any deleted block haven't added yet
            if (contiguousBlockStartAddress != -1)
            {
                if (deletedBlocks != null)
                {
                    deletedBlocks.AddAvailableBlock(contiguousBlockStartAddress,
                                                    contiguousBlockCount * (int)parent.DataBlockSize);
                }
            }
            parent.RegisterChange(true);
        }
예제 #3
0
        /// <summary>
        /// Remove Block from the Collection.
        /// NOTE: this is used by BTreeAlgorithm when deleting a node's and/or
        /// a node's item's data block(s) on disk.
        /// </summary>
        public bool Remove(Algorithm.Collection.ICollectionOnDisk parent, Sop.DataBlock block, bool clearBlock = true)
        {
            if (!parent.File.Server.HasTrashBin)
            {
                return(false);
            }
            // remove block and linked blocks from MRU
            Sop.DataBlock d = block;
            long          contiguousBlockStartAddress = -1;
            long          currentBlockAddress         = -1;
            int           contiguousBlockCount        = 0;

            var deletedBlocks = ((CollectionOnDisk)parent).DeletedBlocks;
            IDictionary <long, Sop.DataBlock> blocks = ((CollectionOnDisk)parent).Blocks;

            if (!d.IsFolded)
            {
                d.Fold();
            }

            if (d.IsFolded)
            {
                if (clearBlock && d.SizeOccupied > 0)
                {
                    d.SizeOccupied = 0;
                }
                foreach (var segment in d.foldedDataAddresses)
                {
                    if (deletedBlocks != null)
                    {
                        RegisterRemovedBlock((CollectionOnDisk)parent, segment.Address, segment.BlockCount * (int)parent.DataBlockSize);
                        // add removed block to the recycle Store for reuse later on Add operation
                        deletedBlocks.AddAvailableBlock(segment.Address, segment.BlockCount * (int)parent.DataBlockSize);
                    }
                }
            }
            else
            {
                #region Legacy code for removing unfolded Blocks
                do
                {
                    if (d.DataAddress >= 0)
                    {
                        blocks.Remove(d.DataAddress);
                    }
                    if (currentBlockAddress >= 0 && currentBlockAddress + (int)parent.DataBlockSize == d.DataAddress)
                    {
                        // if current block is part of a single contiguous block
                        contiguousBlockCount++;
                        currentBlockAddress = d.DataAddress;
                    }
                    else
                    {
                        if (currentBlockAddress != -1)
                        {
                            // recycle segment
                            if (deletedBlocks != null)
                            {
                                RegisterRemovedBlock((CollectionOnDisk)parent, contiguousBlockStartAddress, contiguousBlockCount * (int)parent.DataBlockSize);
                                // add removed block to the recycle Store for reuse later on Add operation
                                deletedBlocks.AddAvailableBlock(contiguousBlockStartAddress,
                                                                contiguousBlockCount * (int)parent.DataBlockSize);
                            }
                        }
                        currentBlockAddress         = d.DataAddress;
                        contiguousBlockStartAddress = d.DataAddress;
                        contiguousBlockCount        = 1;
                    }

                    // clear block's data
                    if (clearBlock && d.SizeOccupied > 0)
                    {
                        d.SizeOccupied = 0;
                    }

                    if (d.Next == null && d.NextItemAddress >= 0)
                    {
                        //load the next datablock to get its next block address...
                        d.Next = ReadBlockFromDisk(parent, parent.FileStream.Position, true, true,
                                                   CreateBlock(parent.DataBlockSize));
                    }

                    d = d.Next;
                } while (d != null);

                // add to deleted blocks store any deleted block haven't added yet
                if (contiguousBlockStartAddress != -1)
                {
                    if (deletedBlocks != null)
                    {
                        RegisterRemovedBlock((CollectionOnDisk)parent, contiguousBlockStartAddress, contiguousBlockCount * (int)parent.DataBlockSize);
                        // add removed block to the recycle Store for reuse later on Add operation
                        deletedBlocks.AddAvailableBlock(contiguousBlockStartAddress,
                                                        contiguousBlockCount * (int)parent.DataBlockSize);
                    }
                }
                #endregion
            }
            parent.RegisterChange(true);
            return(true);
        }