private void RemoveBranchWithOneEntry(TreePage page, TreePage parentPage)
        {
            Debug.Assert(page.NumberOfEntries == 1);

            var pageRefNumber = page.GetNode(0)->PageNumber;

            TreeNodeHeader *nodeHeader = null;

            for (int i = 0; i < parentPage.NumberOfEntries; i++)
            {
                nodeHeader = parentPage.GetNode(i);

                if (nodeHeader->PageNumber == page.PageNumber)
                {
                    break;
                }
            }

            Debug.Assert(nodeHeader->PageNumber == page.PageNumber);

            nodeHeader->PageNumber = pageRefNumber;

            if (_cursor.CurrentPage.PageNumber == page.PageNumber)
            {
                _cursor.Pop();
                _cursor.Push(_tx.GetReadOnlyTreePage(pageRefNumber));
            }

            _tree.FreePage(page);
        }
Exemple #2
0
        private unsafe static void RenderPage(LowLevelTransaction tx, TreePage page, TextWriter sw, string text, bool open)
        {
            sw.WriteLine(
                "<ul><li><input type='checkbox' id='page-{0}' {3} /><label for='page-{0}'>{4}: Page {0:#,#;;0} - {1} - {2:#,#;;0} entries</label><ul>",
                page.PageNumber, page.IsLeaf ? "Leaf" : "Branch", page.NumberOfEntries, open ? "checked" : "", text);

            for (int i = 0; i < page.NumberOfEntries; i++)
            {
                var nodeHeader = page.GetNode(i);
                var key        = TreeNodeHeader.ToSlicePtr(tx.Allocator, nodeHeader).ToString();

                if (page.IsLeaf)
                {
                    sw.Write("<li>{0} {1} - size: {2:#,#}</li>", key, nodeHeader->Flags, TreeNodeHeader.GetDataSize(tx, nodeHeader));
                }
                else
                {
                    var pageNum = nodeHeader->PageNumber;

                    if (i == 0)
                    {
                        key = "[smallest]";
                    }

                    RenderPage(tx, tx.GetReadOnlyTreePage(pageNum), sw, key, false);
                }
            }
            sw.WriteLine("</ul></li></ul>");
        }
 public static byte *DirectAccess(LowLevelTransaction tx, TreeNodeHeader *node)
 {
     if (node->Flags == (TreeNodeFlags.PageRef))
     {
         var overFlowPage = tx.GetReadOnlyTreePage(node->PageNumber);
         return(overFlowPage.Base + Constants.TreePageHeaderSize);
     }
     return((byte *)node + node->KeySize + Constants.NodeHeaderSize);
 }
        public bool MovePrev()
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("TreeIterator " + _tree.Name);
            }
            while (true)
            {
                _currentPage.LastSearchPosition--;
                if (_currentPage.LastSearchPosition >= 0)
                {
                    // run out of entries, need to select the next page...
                    while (_currentPage.IsBranch)
                    {
                        _cursor.Push(_currentPage);
                        var node = _currentPage.GetNode(_currentPage.LastSearchPosition);
                        _currentPage = _tx.GetReadOnlyTreePage(node->PageNumber);
                        _currentPage.LastSearchPosition = _currentPage.NumberOfEntries - 1;

                        if (_prefetch && _currentPage.IsLeaf)
                        {
                            MaybePrefetchOverflowPages(_currentPage);
                        }
                    }
                    var current = _currentPage.GetNode(_currentPage.LastSearchPosition);

                    if (DoRequireValidation && this.ValidateCurrentKey(_tx, current) == false)
                    {
                        return(false);
                    }

                    _currentInternalKey = TreeNodeHeader.ToSlicePtr(_tx.Allocator, current, ByteStringType.Mutable);
                    _currentKey         = _currentInternalKey;
                    return(true);// there is another entry in this page
                }
                if (_cursor.PageCount == 0)
                {
                    break;
                }
                _currentPage = _cursor.Pop();
            }
            _currentPage = null;
            return(false);
        }
        private MultiValuesReport CreateMultiValuesReport(Tree tree)
        {
            var multiValues = new MultiValuesReport();

            using (var multiTreeIterator = tree.Iterate(false))
            {
                if (multiTreeIterator.Seek(Slices.BeforeAllKeys))
                {
                    do
                    {
                        var currentNode = multiTreeIterator.Current;

                        switch (currentNode->Flags)
                        {
                        case TreeNodeFlags.MultiValuePageRef:
                        {
                            var multiValueTreeHeader = (TreeRootHeader *)((byte *)currentNode + currentNode->KeySize + Constants.NodeHeaderSize);

                            Debug.Assert(multiValueTreeHeader->Flags == TreeFlags.MultiValue);

                            multiValues.NumberOfEntries += multiValueTreeHeader->NumberOfEntries;
                            multiValues.BranchPages     += multiValueTreeHeader->BranchPages;
                            multiValues.LeafPages       += multiValueTreeHeader->LeafPages;
                            multiValues.PageCount       += multiValueTreeHeader->PageCount;
                            break;
                        }

                        case TreeNodeFlags.Data:
                        {
                            var nestedPage = GetNestedMultiValuePage(TreeNodeHeader.DirectAccess(_tx, currentNode), currentNode);

                            multiValues.NumberOfEntries += nestedPage.NumberOfEntries;
                            break;
                        }

                        case TreeNodeFlags.PageRef:
                        {
                            var overFlowPage = _tx.GetReadOnlyTreePage(currentNode->PageNumber);
                            var nestedPage   = GetNestedMultiValuePage(overFlowPage.Base + Constants.TreePageHeaderSize, currentNode);

                            multiValues.NumberOfEntries += nestedPage.NumberOfEntries;
                            break;
                        }

                        default:
                            throw new VoronUnrecoverableErrorException("currentNode->FixedTreeFlags has value of " + currentNode->Flags);
                        }
                    } while (multiTreeIterator.MoveNext());
                }
            }
            return(multiValues);
        }
Exemple #6
0
        private Slice GetActualKey(TreePage page, int pos, out TreeNodeHeader *node)
        {
            node = page.GetNode(pos);
            var key = TreeNodeHeader.ToSlicePtr(_tx.Allocator, node);

            while (key.Size == 0)
            {
                Debug.Assert(page.IsBranch);
                page = _tx.GetReadOnlyTreePage(node->PageNumber);
                node = page.GetNode(0);
                key  = TreeNodeHeader.ToSlicePtr(_tx.Allocator, node);
            }

            return(key);
        }
Exemple #7
0
        public static void RenderAndShowTree(LowLevelTransaction tx, long startPageNumber, string headerData = null)
        {
            RenderHtmlTreeView(writer =>
            {
                if (headerData != null)
                {
                    writer.WriteLine(headerData);
                }
                writer.WriteLine("<div class='css-treeview'><ul>");

                var page = tx.GetReadOnlyTreePage(startPageNumber);
                RenderPage(tx, page, writer, "Root", true);

                writer.WriteLine("</ul></div>");
            });
        }
Exemple #8
0
        private void RemoveLeafNode(TreePage page, out ushort nodeVersion)
        {
            var node = page.GetNode(page.LastSearchPosition);

            nodeVersion = node->Version;
            if (node->Flags == (TreeNodeFlags.PageRef)) // this is an overflow pointer
            {
                var overflowPage = _llt.GetReadOnlyTreePage(node->PageNumber);
                FreePage(overflowPage);
            }

            page.RemoveNode(page.LastSearchPosition);
        }