Exemple #1
0
        private static unsafe void RenderPage(Tree tree, 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 {5}</label><ul>",
                page.PageNumber, page.IsLeaf ? "Leaf" : "Branch", page.NumberOfEntries, open ? "checked" : "", text,
                page.IsCompressed? $"(Compressed ({page.CompressionHeader->NumberOfCompressedEntries} entries [uncompressed/compressed: {page.CompressionHeader->UncompressedSize}/{page.CompressionHeader->CompressedSize}])" : string.Empty);

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

                string key;
                Slice  keySlice;
                using (TreeNodeHeader.ToSlicePtr(tree.Llt.Allocator, nodeHeader, out keySlice))
                {
                    key = keySlice.ToString();
                }

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

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

                    RenderPage(tree, tree.GetReadOnlyTreePage(pageNum), sw, key, false);
                }
            }
            sw.WriteLine("</ul></li></ul>");
        }
Exemple #2
0
        protected unsafe Tuple <Slice, Slice> ReadKey(Transaction txh, Tree tree, Slice key)
        {
            TreeNodeHeader *node;

            tree.FindPageFor(key, out node);

            if (node == null)
            {
                return(null);
            }

            Slice item1;

            TreeNodeHeader.ToSlicePtr(txh.Allocator, node, out item1);

            if (!SliceComparer.Equals(item1, key))
            {
                return(null);
            }
            Slice item2;

            Slice.External(txh.Allocator, (byte *)node + node->KeySize + Constants.Tree.NodeHeaderSize, (ushort)node->DataSize, out item2);
            return(Tuple.Create(item1, item2));
        }
Exemple #3
0
        public TreeNodeHeader *Original_WithPrefetch_Search(TreePage page, ByteStringContext allocator, Slice key)
        {
            int numberOfEntries = page.NumberOfEntries;

            if (numberOfEntries == 0)
            {
                goto NoEntries;
            }

            int lastMatch          = -1;
            int lastSearchPosition = 0;

            SliceOptions options = key.Options;

            if (options == SliceOptions.Key)
            {
                if (numberOfEntries == 1)
                {
                    goto SingleEntryKey;
                }

                int low      = page.IsLeaf ? 0 : 1;
                int high     = numberOfEntries - 1;
                int position = 0;

                ushort *offsets = page.KeysOffsets;
                byte *  @base   = page.Base;
                while (low <= high)
                {
                    position = (low + high) >> 1;

                    var node = (TreeNodeHeader *)(@base + offsets[position]);

                    Slice pageKey;
                    using (TreeNodeHeader.ToSlicePtr(allocator, node, out pageKey))
                    {
                        Sse.Prefetch0(pageKey.Content.Ptr);
                        lastMatch = SliceComparer.CompareInline(key, pageKey);
                    }

                    if (lastMatch == 0)
                    {
                        break;
                    }

                    if (lastMatch > 0)
                    {
                        low = position + 1;
                    }
                    else
                    {
                        high = position - 1;
                    }
                }

                if (lastMatch > 0) // found entry less than key
                {
                    position++;    // move to the smallest entry larger than the key
                }

                lastSearchPosition = position;
                goto MultipleEntryKey;
            }
            if (options == SliceOptions.BeforeAllKeys)
            {
                lastMatch = 1;
                goto MultipleEntryKey;
            }
            if (options == SliceOptions.AfterAllKeys)
            {
                lastSearchPosition = numberOfEntries - 1;
                goto MultipleEntryKey;
            }

            return(null);

NoEntries:
            {
                page.LastSearchPosition = 0;
                page.LastMatch          = 1;
                return(null);
            }

SingleEntryKey:
            {
                var node = page.GetNode(0);

                Slice pageKey;
                using (TreeNodeHeader.ToSlicePtr(allocator, node, out pageKey))
                {
                    page.LastMatch = SliceComparer.CompareInline(key, pageKey);
                }

                page.LastSearchPosition = page.LastMatch > 0 ? 1 : 0;
                return(page.LastSearchPosition == 0 ? node : null);
            }

MultipleEntryKey:
            {
                page.LastMatch          = lastMatch;
                page.LastSearchPosition = lastSearchPosition;

                if (lastSearchPosition >= numberOfEntries)
                {
                    return(null);
                }

                return(page.GetNode(lastSearchPosition));
            }
        }