Ejemplo n.º 1
0
        private void DoDisposeNode(NodeId id)
        {
            // If the node is a special node, then we don't dispose it
            if (id.IsSpecial)
            {
                return;
            }

            // Is 'id' a leaf node?
            IMutableArea nodeArea = nodeStore.GetMutableArea(ToInt64StoreAddress(id));

            // Are we a leaf?
            nodeArea.Position = 0;
            int nodeType = nodeArea.ReadInt2();

            if (nodeType == StoreLeafType)
            {
                // Yes, get its reference_count,
                lock (referenceCountLock) {
                    nodeArea.Position = 4;
                    int refCount = nodeArea.ReadInt4();
                    // If the reference_count is >1 then decrement it and return
                    if (refCount > 1)
                    {
                        nodeArea.Position = 4;
                        nodeArea.WriteInt4(refCount - 1);
                        return;
                    }
                }
            }
            else if (nodeType != StoreBranchType)
            {
                // Has to be a branch type, otherwise failure
                throw new IOException("Unknown node type.");
            }
            // 'id' is a none leaf branch or its reference count is 1, so delete the
            // area.

            // NOTE, we delete from the cache first before we delete the area
            //   because the deleted area may be reclaimed immediately and deleting
            //   from the cache after may be too late.

            // Delete from the cache because the given ref may be recycled for a new
            // node at some point.
            lock (branchCache) {
                branchCache.Remove(id);
            }

            // Delete the area
            nodeStore.DeleteArea(ToInt64StoreAddress(id));
        }
Ejemplo n.º 2
0
        public bool LinkLeaf(Key key, NodeId id)
        {
            // If the node is a special node, then we don't need to reference count it.
            if (id.IsSpecial)
            {
                return(true);
            }
            try {
                nodeStore.LockForWrite();

                // Get the area as a MutableArea object
                IMutableArea leafArea = nodeStore.GetMutableArea(ToInt64StoreAddress(id));
                // We synchronize over a reference count lock
                // (Pending: should we lock by area instead?  I'm not sure it will be
                //  worth the complexity of a more fine grained locking mechanism for the
                //  performance improvements - maybe we should implement a locking
                //  mechanism inside MutableArea).
                lock (referenceCountLock) {
                    // Assert this is a leaf
                    leafArea.Position = 0;
                    short nodeType = leafArea.ReadInt2();
                    if (nodeType != StoreLeafType)
                    {
                        throw new IOException("Can only link to a leaf node.");
                    }

                    leafArea.Position = 4;
                    int refCount = leafArea.ReadInt4();
                    // If reference counter is near overflowing, return false.
                    if (refCount > Int32.MaxValue - 8)
                    {
                        return(false);
                    }

                    leafArea.Position = 4;
                    leafArea.WriteInt4(refCount + 1);
                }
                return(true);
            } finally {
                nodeStore.UnlockForWrite();
            }
        }