tiny.machine.checkpoint.roots.maintenance
Defined in checkpoint.roots.
API (15)
Actions
Public operations.
CollectionCapacity.derive: Derives the metadata byte count and the work bound from the limits.SeedCounts.count: Gives how many seeds one owner class holds.SeedCounts.total: Returns the sum of all seed classes as au32.collect: The call traces every owner class the provider snapshotted, then commits one atomic physical sweep.compact: The call opens a manifest chain again, authenticates it, and walks the newest page tree in full before publishing a single manifest with no parent that carries the newest state.
Types and contracts
Public types and contracts.
CollectionCapacity: The collection bounds derived from the limits.CollectionCapacity.DeriveErrorCollectionLimits: A ceiling on seeds, manifest roots, objects, and blocks for one collection.CollectionReport: The physical roots, objects, and blocks one collection retained or removed.CollectionSnapshot: The provider's snapshot of its seeds and physical storage, taken before marking begins.ReachabilityClass: An owner class the provider snapshots, whose manifest roots seed a collection.Retention: What a collection learns when it retains one stored identity.SeedCounts: The number of collection seeds in each owner class.
Values and defaults
Public values and defaults.
Source
Source: lib/machine/src/checkpoint/roots/types.zig:111
zig
/// The collection bounds derived from the limits. The `metadata_bytes` field/// covers the seed roots and the mark arrays. The `work` field caps two things:/// walking the manifest chains and the sweep that ends the collection.pub const CollectionCapacity = struct { limits: CollectionLimits, seeds: u32, metadata_bytes: u64, work: u64, pub const DeriveError: type = CollectionCapacityError; /// Derives the metadata byte count and the work bound from the limits. /// Overflow in any product or sum returns `CollectionCapacityOverflow`. /// Fewer object slots than root slots returns /// `CollectionObjectCapacityTooSmall`. pub fn derive(limits: CollectionLimits) DeriveError!CollectionCapacity { if (limits.roots > limits.objects) { return error.CollectionObjectCapacityTooSmall; } const seeds = limits.seeds.total(); const seed_bytes = std.math.mul( u64, seeds, @sizeOf(ManifestRoot), ) catch return error.CollectionCapacityOverflow; const object_bytes = std.math.mul( u64, limits.objects, @sizeOf(bool), ) catch return error.CollectionCapacityOverflow; const root_bytes = std.math.mul( u64, limits.roots, @sizeOf(bool), ) catch return error.CollectionCapacityOverflow; const block_bytes = std.math.mul( u64, limits.blocks, @sizeOf(bool), ) catch return error.CollectionCapacityOverflow; const metadata_partial = std.math.add( u64, seed_bytes, object_bytes, ) catch return error.CollectionCapacityOverflow; const metadata_roots = std.math.add( u64, metadata_partial, root_bytes, ) catch return error.CollectionCapacityOverflow; const metadata_bytes = std.math.add( u64, metadata_roots, block_bytes, ) catch return error.CollectionCapacityOverflow; const tree_work = std.math.mul( u64, publication_capacity.objects, 4, ) catch return error.CollectionCapacityOverflow; const per_chain_entry = std.math.add( u64, tree_work, 6, ) catch return error.CollectionCapacityOverflow; const per_seed = std.math.mul( u64, chain_limit, per_chain_entry, ) catch return error.CollectionCapacityOverflow; const trace_work = std.math.mul( u64, seeds, per_seed, ) catch return error.CollectionCapacityOverflow; const physical_work = @as(u64, limits.objects) + limits.roots + limits.blocks; return .{ .limits = limits, .seeds = seeds, .metadata_bytes = metadata_bytes, .work = std.math.add( u64, trace_work, physical_work, ) catch return error.CollectionCapacityOverflow, }; }};Source: lib/machine/src/checkpoint/roots/types.zig:96
zig
/// A ceiling on seeds, manifest roots, objects, and blocks for one collection.pub const CollectionLimits = struct { seeds: SeedCounts, roots: u16, objects: u32, blocks: u16,};Source: lib/machine/src/checkpoint/roots/types.zig:208
zig
/// The physical roots, objects, and blocks one collection retained or removed.pub const CollectionReport = struct { retained_roots: u16, collected_roots: u16, retained_objects: u32, collected_objects: u32, retained_blocks: u16, collected_blocks: u16,};Source: lib/machine/src/checkpoint/roots/types.zig:200
zig
/// The provider's snapshot of its seeds and physical storage, taken before/// marking begins.pub const CollectionSnapshot = struct { seeds: SeedCounts, roots: u16, objects: u32, blocks: u16,};Source: lib/machine/src/checkpoint/roots/types.zig:56
zig
/// An owner class the provider snapshots, whose manifest roots seed a/// collection.pub const ReachabilityClass = enum(u8) { chic_world, live_staged_instance, retained_receipt, concurrent_reader,};Source: lib/machine/src/checkpoint/roots/types.zig:221
zig
/// What a collection learns when it retains one stored identity. A `fresh`/// result means this collection marked the identity first, and an `existing`/// result means it had marked it already. The caller uses the result to stop a/// trace from walking the same subtree twice.pub const Retention = enum(u8) { fresh, existing,};Source: lib/machine/src/checkpoint/roots/types.zig:71
zig
/// The number of collection seeds in each owner class.pub const SeedCounts = struct { chic_worlds: u16, live_staged_instances: u16, retained_receipts: u16, concurrent_readers: u16, /// Gives how many seeds one owner class holds. pub fn count(self: SeedCounts, class: ReachabilityClass) u16 { return switch (class) { .chic_world => self.chic_worlds, .live_staged_instance => self.live_staged_instances, .retained_receipt => self.retained_receipts, .concurrent_reader => self.concurrent_readers, }; } /// Returns the sum of all seed classes as a `u32`. The caller uses the /// total to size the work a trace will do. pub fn total(self: SeedCounts) u32 { return @as(u32, self.chic_worlds) + self.live_staged_instances + self.retained_receipts + self.concurrent_readers; }};Source: lib/machine/src/checkpoint/roots/types.zig:315
zig
pub const compaction_capacity = Capacity.derive(compaction_limits) catch unreachable;Source: lib/machine/src/checkpoint/roots/types.zig:309
zig
pub const compaction_limits: Limits = .{ .pages = 0, .nodes = 0, .manifests = 1,};Source: lib/machine/src/checkpoint/roots/maintenance.zig
zig
const manifest = @import("manifest.zig");const owner = @import("owner.zig");const std = @import("std");const tree = @import("tree.zig");const types = @import("types.zig");pub const CollectionCapacity = types.CollectionCapacity;pub const CollectionLimits = types.CollectionLimits;pub const CollectionReport = types.CollectionReport;pub const CollectionSnapshot = types.CollectionSnapshot;pub const ReachabilityClass = types.ReachabilityClass;pub const Retention = types.Retention;pub const SeedCounts = types.SeedCounts;pub const compaction_capacity = types.compaction_capacity;pub const compaction_limits = types.compaction_limits;/// The call opens a manifest chain again, authenticates it, and walks the/// newest page tree in full before publishing a single manifest with no parent/// that carries the newest state. A parentless input returns its existing root/// without publishing anything. Any publication failure aborts the compaction/// transaction. A caller turns a long chain into a single record, so later/// reopens walk one manifest.pub fn compact( storage: types.Storage, expected: types.ManifestRoot,) types.Error!types.Binding { const value = try owner.reopen(storage, expected); try tree.verify(storage, value.pages); if (value.parent == null) { return .{ .root = expected, .manifest = value }; } var compacted = value; compacted.parent = null; compacted.dirty_pages = @intCast(types.page_count); try storage.begin(types.compaction_capacity); var transaction_open = true; defer if (transaction_open) storage.abort(); const root = try manifest.stage(storage, compacted); try storage.commit(root); transaction_open = false; return .{ .root = root, .manifest = compacted };}/// The call traces every owner class the provider snapshotted, then commits one/// atomic physical sweep. The call validates the snapshot against the supplied/// capacity before marking begins, returning `RootCollectionCapacityExceeded`/// when the snapshot exceeds it. A failure during tracing ends the collection/// with no object removed. A caller runs collection to get space back from/// captures nobody holds.pub fn collect( storage: types.Storage, capacity: types.CollectionCapacity,) types.Error!types.CollectionReport { const snapshot = try storage.beginCollection(capacity); var collection_open = true; defer if (collection_open) storage.abortCollection(); try validateSnapshot(capacity, snapshot); inline for (types.reachability_classes) |class| { var index: u16 = 0; while (index < snapshot.seeds.count(class)) : (index += 1) { const root = try storage.readSeed(class, index); try retainRoot(storage, root); } } const report = try storage.commitCollection(); collection_open = false; validateReport(snapshot, report); return report;}fn retainRoot( storage: types.Storage, root: types.ManifestRoot,) types.Error!void { const retention = try storage.retainObject(.manifest, root.digest); if (retention == .existing) return; _ = try owner.openShared(storage, root); var current = root; var depth: usize = 0; while (depth < types.chain_limit) : (depth += 1) { const value = try manifest.read(storage, current); try tree.retain(storage, value.pages); _ = try storage.retainBlock(value.block); if (value.parent) |parent| { const parent_retention = try storage.retainObject( .manifest, parent.digest, ); if (parent_retention == .existing) return; current = parent; } else { return; } } return error.DeltaChainCapacityExceeded;}fn validateSnapshot( capacity: types.CollectionCapacity, snapshot: types.CollectionSnapshot,) types.StorageError!void { const limits = capacity.limits; inline for (types.reachability_classes) |class| { if (snapshot.seeds.count(class) > limits.seeds.count(class)) { return error.RootCollectionCapacityExceeded; } } if (snapshot.roots > limits.roots or snapshot.objects > limits.objects or snapshot.blocks > limits.blocks) { return error.RootCollectionCapacityExceeded; }}fn validateReport( snapshot: types.CollectionSnapshot, report: types.CollectionReport,) void { std.debug.assert( @as(u32, report.retained_roots) + report.collected_roots == snapshot.roots, ); std.debug.assert( report.retained_objects + report.collected_objects == snapshot.objects, ); std.debug.assert( @as(u32, report.retained_blocks) + report.collected_blocks == snapshot.blocks, );}Source: lib/machine/src/checkpoint/roots/root.zig:83
zig
pub const maintenance = @import("maintenance.zig");Audit
| Definitions | 16 |
|---|---|
| Public names | 16 |
| Members | 28 |
| Version | 26.7.0 |
| Revision | daab053ee433 |