Пример #1
0
        public bool Remove(byte[] key)
        {
            _rootNode.TotalSpaceAvailable = _rootNode.CalcSize() + _file.MftRecordFreeSpace(AttributeType.IndexRoot, _name);

            IndexEntry overflowEntry;
            bool       found = _rootNode.RemoveEntry(key, out overflowEntry);

            if (overflowEntry != null)
            {
                throw new IOException("Error removing entry, root overflowed");
            }

            return(found);
        }
Пример #2
0
 public bool Remove(byte[] key)
 {
     _rootNode.TotalSpaceAvailable = _rootNode.CalcSize() + _file.MftRecordFreeSpace(AttributeType.IndexRoot, _name);
     return(_rootNode.RemoveEntry(key));
 }
Пример #3
0
        public bool RemoveEntry(byte[] key, out IndexEntry newParentEntry)
        {
            bool       exactMatch;
            int        entryIndex = GetEntry(key, out exactMatch);
            IndexEntry entry      = _entries[entryIndex];

            if (exactMatch)
            {
                if ((entry.Flags & IndexEntryFlags.Node) != 0)
                {
                    IndexNode  childNode = _index.GetSubBlock(entry).Node;
                    IndexEntry rLeaf     = childNode.FindLargestLeaf();

                    byte[] newKey  = rLeaf.KeyBuffer;
                    byte[] newData = rLeaf.DataBuffer;

                    IndexEntry newEntry;
                    childNode.RemoveEntry(newKey, out newEntry);
                    entry.KeyBuffer  = newKey;
                    entry.DataBuffer = newData;

                    if (newEntry != null)
                    {
                        InsertEntryThisNode(newEntry);
                    }

                    newEntry = LiftNode(entryIndex);
                    if (newEntry != null)
                    {
                        InsertEntryThisNode(newEntry);
                    }

                    newEntry = PopulateEnd();
                    if (newEntry != null)
                    {
                        InsertEntryThisNode(newEntry);
                    }

                    // New entry could be larger than old, so may need
                    // to divide this node...
                    newParentEntry = EnsureNodeSize();
                }
                else
                {
                    _entries.RemoveAt(entryIndex);
                    newParentEntry = null;
                }

                _store();
                return(true);
            }
            else if ((entry.Flags & IndexEntryFlags.Node) != 0)
            {
                IndexNode  childNode = _index.GetSubBlock(entry).Node;
                IndexEntry newEntry;
                if (childNode.RemoveEntry(key, out newEntry))
                {
                    if (newEntry != null)
                    {
                        InsertEntryThisNode(newEntry);
                    }

                    newEntry = LiftNode(entryIndex);
                    if (newEntry != null)
                    {
                        InsertEntryThisNode(newEntry);
                    }

                    newEntry = PopulateEnd();
                    if (newEntry != null)
                    {
                        InsertEntryThisNode(newEntry);
                    }

                    // New entry could be larger than old, so may need
                    // to divide this node...
                    newParentEntry = EnsureNodeSize();

                    _store();
                    return(true);
                }
            }

            newParentEntry = null;
            return(false);
        }
Пример #4
0
        public bool RemoveEntry(byte[] key)
        {
            bool       exactMatch;
            int        entryIndex = GetEntry(key, out exactMatch);
            IndexEntry entry      = _entries[entryIndex];

            if (exactMatch)
            {
                if ((entry.Flags & IndexEntryFlags.Node) != 0)
                {
                    // Get the next biggest entry in the index, which may be sibling or descendant of sibling
                    IndexEntry replacementLeaf = _entries[entryIndex + 1];
                    if ((replacementLeaf.Flags & (IndexEntryFlags.End | IndexEntryFlags.Node)) == IndexEntryFlags.End)
                    {
                        entry.KeyBuffer  = null;
                        entry.DataBuffer = null;
                        entry.Flags     |= IndexEntryFlags.End;
                        _entries.RemoveAt(entryIndex + 1);
                    }
                    else
                    {
                        if ((replacementLeaf.Flags & IndexEntryFlags.Node) != 0)
                        {
                            IndexNode giftingNode = _index.GetSubBlock(this, replacementLeaf).Node;
                            replacementLeaf = giftingNode.FindSmallestLeaf();
                        }

                        // Take a reference to the byte arrays because in the recursive case, these arrays
                        // may be changed as a new node is promoted.
                        byte[] newKey  = replacementLeaf.KeyBuffer;
                        byte[] newData = replacementLeaf.DataBuffer;

                        RemoveEntry(newKey);

                        // Just over-write our key & data with the replacement
                        entry.KeyBuffer  = newKey;
                        entry.DataBuffer = newData;

                        LiftNode(entryIndex + 1);
                    }
                }
                else
                {
                    _entries.RemoveAt(entryIndex);
                }

                _store();
                return(true);
            }
            else
            {
                if ((entry.Flags & IndexEntryFlags.Node) != 0)
                {
                    IndexNode childNode = _index.GetSubBlock(this, entry).Node;
                    if (childNode.RemoveEntry(key))
                    {
                        LiftNode(entryIndex);

                        _store();
                        return(true);
                    }
                }
                else
                {
                    return(false);
                }
            }

            return(false);
        }