Example #1
0
 public void Dispose()
 {
     if (_disposed)
     {
         return;
     }
     _disposed = true;
     if (RequiredPrefix.HasValue)
     {
         RequiredPrefix.Release(_tx.Allocator);
     }
     if (MaxKey.HasValue)
     {
         MaxKey.Release(_tx.Allocator);
     }
     _prevKeyScope.Dispose();
     _cursor?.Dispose();
     _decompressedPage?.Dispose();
     OnDisposal?.Invoke(this);
 }
Example #2
0
        private static async Task RenderPageInternalAsync(Tree tree, TreePageSafe page, TextWriter sw, string text, bool open, bool decompress)
        {
            await sw.WriteLineAsync(
                string.Format("<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.NumberOfCompressedEntries} entries [uncompressed/compressed: {page.UncompressedSize}/{page.CompressedSize}])" : string.Empty));

            DecompressedLeafPage decompressedPage = null;

            if (page.IsCompressed && decompress)
            {
                decompressedPage = tree.DecompressPage(page.TreePage, DecompressionUsage.Read, skipCache: true);

                page = new TreePageSafe(page.Tree, decompressedPage);
            }

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

                    string key = nodeHeader.Key;

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

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

                        await RenderPageAsync(tree, tree.GetReadOnlyTreePage(pageNum), sw, key, false, decompress);
                    }
                }
            }
            finally
            {
                decompressedPage?.Dispose();
            }

            await sw.WriteLineAsync("</ul></li></ul>");
        }
Example #3
0
        private ActualKeyScope GetActualKey(TreePage page, int pos, out TreeNodeHeader *node, out Slice key)
        {
            DecompressedLeafPage decompressedLeafPage = null;

            node = page.GetNode(pos);
            var scope = TreeNodeHeader.ToSlicePtr(_tx.Allocator, node, out key);

            while (key.Size == 0)
            {
                Debug.Assert(page.IsBranch);
                page = _tree.GetReadOnlyTreePage(node->PageNumber);
                if (page.IsCompressed == false)
                {
                    node = page.GetNode(0);
                }
                else
                {
                    decompressedLeafPage?.Dispose();
                    decompressedLeafPage = _tree.DecompressPage(page, skipCache: true);

                    if (decompressedLeafPage.NumberOfEntries > 0)
                    {
                        node = decompressedLeafPage.GetNode(0);
                    }
                    else
                    {
                        // we have empty page after decompression (each compressed entry has a corresponding CompressionTombstone)
                        // we can safely use the node key of first tombstone (they have proper order)

                        node = page.GetNode(0);
                    }
                }

                scope.Dispose();
                scope = TreeNodeHeader.ToSlicePtr(_tx.Allocator, node, out key);
            }

            return(new ActualKeyScope
            {
                DecompressedLeafPage = decompressedLeafPage,
                ExternalScope = scope
            });
        }
Example #4
0
        public void Dispose()
        {
            if (_disposed)
            {
                return;
            }

            _disposed = true;

            if (_isLeaf)
            {
                DecompressedLeaf?.Dispose();
            }
            else
            {
                foreach (var reduceTreePage in Children)
                {
                    reduceTreePage.Dispose();
                }
            }

            GC.SuppressFinalize(this);
        }
Example #5
0
 public void Dispose()
 {
     ExternalScope.Dispose();
     DecompressedLeafPage?.Dispose();
 }
Example #6
0
        private ActualKeyScope GetActualKey(TreePage page, int pos, out TreeNodeHeader *node, out Slice key)
        {
            DecompressedLeafPage decompressedLeafPage = null;

            node = page.GetNode(pos);
            var scope = TreeNodeHeader.ToSlicePtr(_tx.Allocator, node, out key);

            while (key.Size == 0)
            {
                Debug.Assert(page.IsBranch);
                page = _tree.GetReadOnlyTreePage(node->PageNumber);
                if (page.IsCompressed == false)
                {
                    node = page.GetNode(0);
                }
                else
                {
                    decompressedLeafPage?.Dispose();
                    decompressedLeafPage = _tree.DecompressPage(page, DecompressionUsage.Read, skipCache: true);

                    if (decompressedLeafPage.NumberOfEntries > 0)
                    {
                        if (page.NumberOfEntries == 0)
                        {
                            node = decompressedLeafPage.GetNode(0);
                        }
                        else
                        {
                            // we want to find the smallest key in compressed page
                            // it can be inside compressed part or not compressed one
                            // in particular, it can be the key of compression tombstone node that we don't see after decompression
                            // so we need to take first keys from decompressed and compressed page and compare them

                            var decompressedNode = decompressedLeafPage.GetNode(0);
                            var compressedNode   = page.GetNode(0);

                            using (TreeNodeHeader.ToSlicePtr(_tx.Allocator, decompressedNode, out var firstDecompressedKey))
                                using (TreeNodeHeader.ToSlicePtr(_tx.Allocator, compressedNode, out var firstCompressedKey))
                                {
                                    node = SliceComparer.CompareInline(firstDecompressedKey, firstCompressedKey) > 0 ? compressedNode : decompressedNode;
                                }
                        }
                    }
                    else
                    {
                        // we have empty page after decompression (each compressed entry has a corresponding CompressionTombstone)
                        // we can safely use the node key of first tombstone (they have proper order)

                        node = page.GetNode(0);
                    }
                }

                scope.Dispose();
                scope = TreeNodeHeader.ToSlicePtr(_tx.Allocator, node, out key);
            }

            return(new ActualKeyScope
            {
                DecompressedLeafPage = decompressedLeafPage,
                ExternalScope = scope
            });
        }