Skip to documentation
SLOP

tiny.sql.Tree

Reference tiny.sql Tree

Defined in tree.

API (22)

Actions

Public operations.

Fields and members

Public fields and members.

No direct callersNo direct callstreeTree
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Source: lib/sql/src/tree.zig:890

zig
pub const Tree = struct {    database: *file.Database,    meta_page: u32,    root_page: u32,    identity_page: u32,    reserved_page_max: u32,    pub fn open(database: *file.Database, options: Options) Error!Tree {        const reserved_page_max = try validateOptions(options);        return .{            .database = database,            .meta_page = options.meta_page,            .root_page = options.root_page,            .identity_page = options.identity_page,            .reserved_page_max = reserved_page_max,        };    }    pub fn reader(self: *const Tree, snapshot: file.Snapshot) Error!Reader {        return .{            .snapshot = snapshot,            .meta_page = self.meta_page,            .root_page = self.root_page,            .identity_page = self.identity_page,            .reserved_page_max = self.reserved_page_max,        };    }    pub fn identity(self: *const Tree) Error!TreeIdentity {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.identity();    }    /// Returns the digest of `identity_value`, an identity this tree read    /// from its identity page, through its database's memo.    pub fn digestIdentity(        self: *const Tree,        identity_value: *const TreeIdentity,    ) [lattice.digest_size]u8 {        return self.database.digest_memo.digest(            self.identity_page,            &identity_value.state,            identity_value.entries,        );    }    pub fn get(self: *const Tree, allocator: Allocator, key: []const u8) Error!?[]u8 {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.get(allocator, key);    }    pub fn valueLength(self: *const Tree, key: []const u8) Error!?usize {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.valueLength(key);    }    pub fn getInto(self: *const Tree, key: []const u8, target: []u8) Error!?[]u8 {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.getInto(key, target);    }    pub fn lastKey(self: *const Tree, buffer: []u8) Error!?[]const u8 {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.lastKey(buffer);    }    pub fn put(self: *Tree, key: []const u8, value: []const u8, options: file.CommitOptions) Error!file.Commit {        const phase = trace.scope("tree.put");        defer phase.end();        var write = try Write.beginTree(self);        defer write.deinit();        try write.put(self, key, value);        return try write.commit(options);    }    fn putInWrite(self: *Tree, write: *Write, key: []const u8, value: []const u8) Error!void {        var pending_storage: PendingPut = undefined;        var pending: ?*PendingPut = null;        if (try write.identityScratch(self)) |scratch| {            var hasher = lattice.EntryHasher.init(key);            hasher.update(value);            pending_storage = .{                .scratch = scratch,                .fresh = hasher.finish(),                .key_len = key.len,                .value_len = value.len,            };            pending = &pending_storage;        }        var inline_buffer: [inline_value_max + 1]u8 = undefined;        var overflow_buffer: [record.overflow_size]u8 = undefined;        const value_record = try self.writeValueRecord(write, value, &inline_buffer, &overflow_buffer);        var root_scratch: [page.size]u8 = undefined;        switch (try write.readRootPage(self, &root_scratch)) {            .leaf => |leaf| try self.putRootLeaf(write, leaf, key, value_record, pending),            .branch => |branch| try self.putRootBranch(write, branch, key, value_record, pending),        }    }    fn applyPutIdentity(self: *const Tree, write: *Write, pending: ?*PendingPut, key: []const u8, old_record: ?[]const u8) Error!void {        const pending_put = pending orelse return;        if (old_record) |encoded| {            const old = try self.entryStateFromRecord(write, key, encoded);            pending_put.scratch.state.subtract(&old.state);            pending_put.scratch.value_bytes -= old.value_len;        } else {            pending_put.scratch.entries += 1;            pending_put.scratch.key_bytes += pending_put.key_len;        }        pending_put.scratch.value_bytes += pending_put.value_len;        pending_put.scratch.state.add(&pending_put.fresh);        pending_put.scratch.dirty = true;    }    fn applyDeleteIdentity(self: *const Tree, write: *Write, scratch: ?*IdentityScratch, key: []const u8, old_record: []const u8) Error!void {        const identity_scratch = scratch orelse return;        const old = try self.entryStateFromRecord(write, key, old_record);        identity_scratch.state.subtract(&old.state);        identity_scratch.entries -= 1;        identity_scratch.key_bytes -= key.len;        identity_scratch.value_bytes -= old.value_len;        identity_scratch.dirty = true;    }    fn entryStateFromRecord(self: *const Tree, write: *Write, key: []const u8, value_record: []const u8) Error!OldEntry {        _ = self;        var hasher = lattice.EntryHasher.init(key);        var value_len: u64 = 0;        switch (try record.kind(value_record)) {            .inline_value => {                const inline_value = try record.inlineValue(value_record);                value_len = inline_value.len;                hasher.update(inline_value);            },            .overflow => {                const overflow = try record.overflow(value_record);                value_len = overflow.len;                var remaining = try overflowLengthAsUsize(overflow.len);                var page_id = overflow.first_page;                while (page_id != 0) {                    var image: [page.size]u8 = undefined;                    try write.readExistingPage(page_id, &image);                    const overflow_page = try page.Overflow.load(&image);                    const expected = @min(page.overflow_capacity, remaining);                    if (overflow_page.content().len != expected) return error.InvalidPage;                    hasher.update(overflow_page.content());                    const next_page = overflow_page.next();                    remaining -= expected;                    if (remaining == 0 and next_page != 0) return error.InvalidPage;                    if (remaining > 0 and next_page == 0) return error.InvalidPage;                    page_id = next_page;                }                if (remaining != 0) return error.InvalidPage;            },        }        return .{ .state = hasher.finish(), .value_len = value_len };    }    pub fn delete(self: *Tree, key: []const u8, options: file.CommitOptions) Error!file.Commit {        const phase = trace.scope("tree.delete");        defer phase.end();        var write = try Write.beginTree(self);        defer write.deinit();        try write.delete(self, key);        return try write.commit(options);    }    fn deleteInWrite(self: *Tree, write: *Write, key: []const u8) Error!void {        const scratch = try write.identityScratch(self);        var root_scratch: [page.size]u8 = undefined;        switch (try write.readRootPage(self, &root_scratch)) {            .leaf => |loaded| {                var leaf = loaded;                const old_record = leaf.get(key) orelse return error.KeyNotFound;                try self.applyDeleteIdentity(write, scratch, key, old_record);                const old_overflow = try overflowRefOrNull(old_record);                try leaf.delete(key);                if (old_overflow) |overflow| try self.releaseOverflowValue(write, overflow);                try write.putPage(self.root_page, leaf.bytes);            },            .branch => |branch| try self.deleteRootBranch(write, branch, key, scratch),        }    }    pub fn clear(self: *Tree, options: file.CommitOptions) Error!file.Commit {        const phase = trace.scope("tree.clear");        defer phase.end();        var write = try Write.beginTree(self);        defer write.deinit();        try write.clear(self);        return try write.commit(options);    }    fn clearInWrite(self: *Tree, write: *Write) Error!void {        var root_image: [page.size]u8 = undefined;        try write.readRoot(self, &root_image);        var pages: std.ArrayList(u32) = .empty;        defer pages.deinit(write.database.allocator);        try self.collectReleasedPages(write, &root_image, 0, &pages);        std.mem.sort(u32, pages.items, {}, PageIdSort.desc);        for (pages.items) |page_id| try write.releasePage(self.root_page, page_id);        _ = page.Leaf.init(&root_image, self.root_page);        try write.putPage(self.root_page, &root_image);        if (try write.identityScratch(self)) |scratch| {            scratch.state = lattice.State.empty;            scratch.entries = 0;            scratch.key_bytes = 0;            scratch.value_bytes = 0;            scratch.dirty = true;        }    }    pub fn range(        self: *const Tree,        target: *Range,        allocator: Allocator,        start: ?[]const u8,        end: ?[]const u8,    ) Error!void {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        try opened.range(target, allocator, start, end);    }    pub fn scan(        self: *const Tree,        target: *Scan,        allocator: Allocator,        start: ?[]const u8,        end: ?[]const u8,        projection: Projection,    ) Error!void {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        try opened.scan(target, allocator, start, end, projection);    }    pub fn summarize(self: *const Tree) Error!Summary {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.summarize();    }    pub fn count(self: *const Tree) Error!usize {        var read = try self.database.beginRead();        defer read.deinit();        const opened = try self.reader(read.snapshot());        return try opened.count();    }    pub fn summarizeIn(self: *const Tree, write: *const Write) Error!Summary {        const phase = trace.scope("tree.summarize_in");        defer phase.end();        try write.ensureTree(self);        var root_image: [page.size]u8 = undefined;        try write.readRoot(self, &root_image);        var summary = Summary{};        try summarizePage(write, &root_image, 0, &summary);        return summary;    }    pub fn root(self: *const Tree, allocator: Allocator) Error!Root {        const phase = trace.scope("tree.root");        defer phase.end();        var read = try self.database.beginRead();        defer read.deinit();        const snapshot = read.snapshot();        if (self.database.tree_roots.find(self.root_page, snapshot.view.base_generation, snapshot.view.end_mark)) |cached| {            return try cached.clone(allocator);        }        var root_image: [page.size]u8 = undefined;        _ = try readRoot(snapshot, self.root_page, &root_image);        var build = RootBuild.init(allocator);        errdefer build.deinit();        _ = try build.appendNode(snapshot, &root_image, &.{}, null, 0);        const built = try build.finish();        self.database.tree_roots.store(            self.database.allocator,            self.root_page,            snapshot.view.base_generation,            snapshot.view.end_mark,            &built,        ) catch {};        return built;    }    fn putRootLeaf(        self: *Tree,        write: *Write,        loaded: page.Leaf,        key: []const u8,        value_record: []const u8,        pending: ?*PendingPut,    ) Error!void {        var leaf = loaded;        const root_image = leaf.bytes;        const old_record = leaf.get(key);        try self.applyPutIdentity(write, pending, key, old_record);        const old_overflow = try overflowRefOrNull(old_record);        leaf.put(key, value_record) catch |err| switch (err) {            error.PageFull => {                const first_child = try write.allocatePage();                const second_child = try write.allocatePage();                var left_image: [page.size]u8 = undefined;                var right_image: [page.size]u8 = undefined;                var left = page.Leaf.init(&left_image, first_child);                var right = page.Leaf.init(&right_image, second_child);                const separator = leaf.splitPut(&left, &right, key, value_record) catch |split_err| switch (split_err) {                    error.PageFull => return error.KeyTooLarge,                    else => return split_err,                };                var branch = page.Branch.init(root_image, self.root_page);                try branch.put(&.{}, first_child);                try branch.put(separator, second_child);                if (old_overflow) |overflow| try self.releaseOverflowValue(write, overflow);                try write.putPage(self.root_page, root_image);                try write.putPage(first_child, &left_image);                try write.putPage(second_child, &right_image);                return;            },            else => return err,        };        if (old_overflow) |overflow| try self.releaseOverflowValue(write, overflow);        try write.putPage(self.root_page, root_image);    }    fn putRootBranch(        self: *Tree,        write: *Write,        loaded: page.Branch,        key: []const u8,        value_record: []const u8,        pending: ?*PendingPut,    ) Error!void {        var branch = loaded;        const root_image = branch.bytes;        const child_id = branch.childFor(key);        const split = (try self.putNonRoot(write, child_id, key, value_record, 1, pending)) orelse return;        branch.put(split.key(), split.child) catch |err| switch (err) {            error.PageFull => {                const left_child = try write.allocatePage();                const right_child = try write.allocatePage();                var left_image: [page.size]u8 = undefined;                var right_image: [page.size]u8 = undefined;                var left = page.Branch.init(&left_image, left_child);                var right = page.Branch.init(&right_image, right_child);                const separator = branch.splitPut(&left, &right, split.key(), split.child) catch |split_err| switch (split_err) {                    error.PageFull => return error.KeyTooLarge,                    else => return split_err,                };                const left_lower = left.firstLower() orelse return error.InvalidPage;                var new_root = page.Branch.init(root_image, self.root_page);                try new_root.put(left_lower, left_child);                try new_root.put(separator, right_child);                try write.putPage(self.root_page, root_image);                try write.putPage(left_child, &left_image);                try write.putPage(right_child, &right_image);                return;            },            else => return err,        };        try write.putPage(self.root_page, root_image);    }    fn putNonRoot(self: *Tree, write: *Write, page_id: u32, key: []const u8, value_record: []const u8, depth: usize, pending: ?*PendingPut) Error!?Separator {        if (depth >= max_height) return error.TreeTooDeep;        var scratch: [page.size]u8 = undefined;        return switch (try write.readTreePage(page_id, &scratch)) {            .leaf => |leaf| try self.putLeaf(write, leaf, page_id, key, value_record, pending),            .branch => |branch| try self.putBranch(                write,                branch,                page_id,                key,                value_record,                depth,                pending,            ),        };    }    fn putLeaf(        self: *Tree,        write: *Write,        loaded: page.Leaf,        page_id: u32,        key: []const u8,        value_record: []const u8,        pending: ?*PendingPut,    ) Error!?Separator {        var leaf = loaded;        const image = leaf.bytes;        const old_record = leaf.get(key);        try self.applyPutIdentity(write, pending, key, old_record);        const old_overflow = try overflowRefOrNull(old_record);        leaf.put(key, value_record) catch |err| switch (err) {            error.PageFull => {                const new_child = try write.allocatePage();                var left_image: [page.size]u8 = undefined;                var right_image: [page.size]u8 = undefined;                var left = page.Leaf.init(&left_image, page_id);                var right = page.Leaf.init(&right_image, new_child);                const separator = leaf.splitPut(&left, &right, key, value_record) catch |split_err| switch (split_err) {                    error.PageFull => return error.KeyTooLarge,                    else => return split_err,                };                if (old_overflow) |overflow| try self.releaseOverflowValue(write, overflow);                try write.putPage(page_id, &left_image);                try write.putPage(new_child, &right_image);                return try Separator.init(separator, new_child);            },            else => return err,        };        if (old_overflow) |overflow| try self.releaseOverflowValue(write, overflow);        try write.putPage(page_id, image);        return null;    }    fn putBranch(        self: *Tree,        write: *Write,        loaded: page.Branch,        page_id: u32,        key: []const u8,        value_record: []const u8,        depth: usize,        pending: ?*PendingPut,    ) Error!?Separator {        var branch = loaded;        const image = branch.bytes;        const child_id = branch.childFor(key);        const split = (try self.putNonRoot(write, child_id, key, value_record, depth + 1, pending)) orelse return null;        branch.put(split.key(), split.child) catch |err| switch (err) {            error.PageFull => {                const new_child = try write.allocatePage();                var left_image: [page.size]u8 = undefined;                var right_image: [page.size]u8 = undefined;                var left = page.Branch.init(&left_image, page_id);                var right = page.Branch.init(&right_image, new_child);                const separator = branch.splitPut(&left, &right, split.key(), split.child) catch |split_err| switch (split_err) {                    error.PageFull => return error.KeyTooLarge,                    else => return split_err,                };                try write.putPage(page_id, &left_image);                try write.putPage(new_child, &right_image);                return try Separator.init(separator, new_child);            },            else => return err,        };        try write.putPage(page_id, image);        return null;    }    fn deleteRootBranch(        self: *Tree,        write: *Write,        loaded: page.Branch,        key: []const u8,        scratch: ?*IdentityScratch,    ) Error!void {        var branch = loaded;        const root_image = branch.bytes;        const child_index = branch.childIndexFor(key);        const child_id = branch.childAt(child_index);        const result = try self.deleteNonRoot(write, child_id, key, 1, scratch);        switch (result) {            .empty => {                try branch.remove(child_index);                try write.releasePage(self.root_page, child_id);            },            .lower => |lower| {                const replacement = if (child_index == 0 and branch.lowerAt(0).len == 0) branch.lowerAt(0) else lower.key();                try replaceLowerBoundIfFits(&branch, child_index, replacement, child_id);            },        }        if (branch.cellCount() == 0) {            _ = page.Leaf.init(root_image, self.root_page);            try write.putPage(self.root_page, root_image);            return;        }        try self.compactRoot(write, root_image, 0);    }    fn deleteNonRoot(self: *Tree, write: *Write, page_id: u32, key: []const u8, depth: usize, scratch: ?*IdentityScratch) Error!DeleteResult {        if (depth >= max_height) return error.TreeTooDeep;        var page_scratch: [page.size]u8 = undefined;        switch (try write.readTreePage(page_id, &page_scratch)) {            .leaf => |loaded| {                var leaf = loaded;                const old_record = leaf.get(key) orelse return error.KeyNotFound;                try self.applyDeleteIdentity(write, scratch, key, old_record);                const old_overflow = try overflowRefOrNull(old_record);                try leaf.delete(key);                if (old_overflow) |overflow| try self.releaseOverflowValue(write, overflow);                if (leaf.cellCount() == 0) return .empty;                try write.putPage(page_id, leaf.bytes);                return .{ .lower = try Separator.init(leaf.firstKey() orelse return error.InvalidPage, page_id) };            },            .branch => |loaded| {                var branch = loaded;                const child_index = branch.childIndexFor(key);                const child_id = branch.childAt(child_index);                const result = try self.deleteNonRoot(write, child_id, key, depth + 1, scratch);                switch (result) {                    .empty => {                        try branch.remove(child_index);                        try write.releasePage(self.root_page, child_id);                    },                    .lower => |lower| {                        const replacement = if (child_index == 0 and branch.lowerAt(0).len == 0) branch.lowerAt(0) else lower.key();                        try replaceLowerBoundIfFits(&branch, child_index, replacement, child_id);                    },                }                if (branch.cellCount() == 0) return .empty;                try write.putPage(page_id, branch.bytes);                return .{ .lower = try Separator.init(branch.firstLower() orelse return error.InvalidPage, page_id) };            },        }    }    fn replaceLowerBoundIfFits(branch: *page.Branch, index: usize, lower: []const u8, child: u32) Error!void {        branch.replace(index, lower, child) catch |err| switch (err) {            error.PageFull => {},            else => return err,        };    }    fn compactRoot(self: *Tree, write: *Write, root_image: *[page.size]u8, depth: usize) Error!void {        if (depth >= max_height) return error.TreeTooDeep;        switch (try page.kind(root_image)) {            .leaf => try write.putPage(self.root_page, root_image),            .branch => {                const branch = try page.Branch.load(root_image);                if (branch.cellCount() == 1) {                    var child: [page.size]u8 = undefined;                    const child_id = branch.childAt(0);                    try write.readExistingPage(child_id, &child);                    try copyRootPage(root_image, &child, self.root_page);                    try write.releasePage(self.root_page, child_id);                    try self.compactRoot(write, root_image, depth + 1);                    return;                }                try write.putPage(self.root_page, root_image);            },            .meta => return error.InvalidPage,            .overflow => return error.InvalidPage,            .identity => return error.InvalidPage,        }    }    fn writeValueRecord(self: *Tree, write: *Write, value: []const u8, inline_buffer: *[inline_value_max + 1]u8, overflow_buffer: *[record.overflow_size]u8) Error![]const u8 {        if (value.len <= inline_value_max) return try record.encodeInline(inline_buffer, value);        if (value.len > std.math.maxInt(u64)) return error.ValueTooLarge;        const first_page = try self.writeOverflowValue(write, value);        return try record.encodeOverflow(overflow_buffer, .{            .len = @intCast(value.len),            .first_page = first_page,        });    }    fn writeOverflowValue(self: *Tree, write: *Write, value: []const u8) Error!u32 {        _ = self;        if (value.len == 0) return error.ValueTooLarge;        var offset: usize = 0;        const first_page = try write.allocatePage();        var current_page = first_page;        while (offset < value.len) {            const remaining = value.len - offset;            const chunk_len = @min(page.overflow_capacity, remaining);            const next_page = if (offset + chunk_len < value.len) try write.allocatePage() else 0;            var image: [page.size]u8 = undefined;            _ = try page.Overflow.init(&image, current_page, next_page, value[offset..][0..chunk_len]);            try write.putPage(current_page, &image);            current_page = next_page;            offset += chunk_len;        }        return first_page;    }    fn releaseOverflowValue(self: *const Tree, write: *Write, overflow: record.Overflow) Error!void {        var pages: std.ArrayList(u32) = .empty;        defer pages.deinit(write.database.allocator);        try self.collectOverflowPages(write, overflow, &pages);        for (pages.items) |page_id| try write.releasePage(self.root_page, page_id);    }    fn collectReleasedPages(self: *const Tree, write: *Write, image: *[page.size]u8, depth: usize, pages: *std.ArrayList(u32)) Error!void {        if (depth >= max_height) return error.TreeTooDeep;        switch (try page.kind(image)) {            .leaf => {                const leaf = try page.Leaf.load(image);                var leaf_range = try leaf.range(null, null);                while (leaf_range.next()) |entry| {                    if (try overflowRefOrNull(entry.value)) |overflow| try self.collectOverflowPages(write, overflow, pages);                }            },            .branch => {                const branch = try page.Branch.load(image);                var index: usize = 0;                while (index < branch.cellCount()) : (index += 1) {                    const child_id = branch.childAt(index);                    var child_image: [page.size]u8 = undefined;                    try write.readExistingPage(child_id, &child_image);                    try self.collectReleasedPages(write, &child_image, depth + 1, pages);                    try pages.append(write.database.allocator, child_id);                }            },            .meta => return error.InvalidPage,            .overflow => return error.InvalidPage,            .identity => return error.InvalidPage,        }    }    fn collectOverflowPages(self: *const Tree, write: *Write, overflow: record.Overflow, pages: *std.ArrayList(u32)) Error!void {        _ = self;        var remaining = try overflowLengthAsUsize(overflow.len);        var page_id = overflow.first_page;        while (page_id != 0) {            var image: [page.size]u8 = undefined;            try write.readExistingPage(page_id, &image);            const overflow_page = try page.Overflow.load(&image);            const expected = @min(page.overflow_capacity, remaining);            if (overflow_page.content().len != expected) return error.InvalidPage;            const next_page = overflow_page.next();            try pages.append(write.database.allocator, page_id);            remaining -= expected;            if (remaining == 0 and next_page != 0) return error.InvalidPage;            if (remaining > 0 and next_page == 0) return error.InvalidPage;            page_id = next_page;        }        if (remaining != 0) return error.InvalidPage;    }};

Source: lib/sql/src/root.zig:211

zig
pub const Tree = tree.Tree;
Called byCallsNo direct callersTreeWritebeginTreeTreeclear
Static calls · unresolved targets: 1 · external targets: 4.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreecount
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersTreeWritebeginTreeTreedelete
Static calls · unresolved targets: 0 · external targets: 5.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreeget
Static calls · unresolved targets: 1 · external targets: 2.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreegetInto
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreeidentity
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreelastKey
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsIndexopenRowIdTableopentest sourcelib.sql.src.treetest: allocated roots clear recycled ...test sourcelib.sql.src.treetest: tree accepts every fitting key ...test sourcelib.sql.src.treetest: tree clear releases durable pag...+37 moreprivate sourcelib.sql.src.treevalidateOptionsTreeopen
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersTreeWritebeginTreeTreeput
Static calls · unresolved targets: 1 · external targets: 4.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreerange
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callsIndexreaderRowIdTablereaderTreecountTreegetTreegetInto+6 moreTreereader
Static calls · unresolved targets: 0 · external targets: 0.
Called byCallsNo direct callersFileDatabasebeginReadprivate sourcelib.sql.src.tree.RootBuildappendNodeprivate sourcelib.sql.src.tree.RootBuilddeinitprivate sourcelib.sql.src.tree.RootBuildfinishprivate sourcelib.sql.src.tree.RootBuildinitprivate sourcelib.sql.src.treereadRootTreeroot
Static calls · unresolved targets: 0 · external targets: 7.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreescan
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreesummarize
Static calls · unresolved targets: 0 · external targets: 3.
Called byCallsIndexsummarizeInRowIdTablesummarizeInprivate sourcelib.sql.src.treesummarizePageTreesummarizeIn
Static calls · unresolved targets: 0 · external targets: 4.
Called byCallsNo direct callersFileDatabasebeginReadTreereaderTreevalueLength
Static calls · unresolved targets: 0 · external targets: 3.

Complete caller list for Tree.open

42 direct callers.

Complete caller list for Tree.reader

11 direct callers.

Audit

Definitions18
Public names36
Members5
Version26.7.0
Revisiondaab053ee433