コード例 #1
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);
        }