Skip to main content

TreeStats

Struct TreeStats 

Source
pub struct TreeStats {
Show 29 fields pub num_nodes: usize, pub num_leaves: usize, pub num_internal_nodes: usize, pub tree_height: u8, pub total_key_value_pairs: usize, pub total_tree_size_bytes: usize, pub avg_node_size_bytes: f64, pub min_node_size_bytes: usize, pub max_node_size_bytes: usize, pub avg_entries_per_node: f64, pub nodes_per_level: BTreeMap<u8, usize>, pub avg_node_size_per_level: BTreeMap<u8, f64>, pub avg_entries_per_level: BTreeMap<u8, f64>, pub min_entries_per_level: BTreeMap<u8, usize>, pub max_entries_per_level: BTreeMap<u8, usize>, pub avg_fanout: f64, pub min_fanout: usize, pub max_fanout: usize, pub avg_fill_factor: f64, pub avg_leaf_fill_factor: f64, pub avg_internal_fill_factor: f64, pub avg_key_size_bytes: f64, pub avg_value_size_bytes: f64, pub min_key_size_bytes: usize, pub max_key_size_bytes: usize, pub min_value_size_bytes: usize, pub max_value_size_bytes: usize, pub total_keys_size_bytes: usize, pub total_values_size_bytes: usize, /* private fields */
}
Expand description

Statistics about a Prolly tree structure

This struct contains comprehensive metrics about a Prolly tree, including structure, size, distribution, and efficiency information. Statistics are collected through a single tree traversal using Prolly::collect_stats.

§Fields

§Basic Structure

  • num_nodes: Total number of nodes in the tree
  • num_leaves: Number of leaf nodes (containing key-value pairs)
  • num_internal_nodes: Number of internal nodes (containing child pointers)
  • tree_height: Maximum level in the tree (0 for single-node trees)
  • total_key_value_pairs: Total number of key-value pairs stored

§Size Statistics

  • total_tree_size_bytes: Total serialized size of all nodes
  • avg_node_size_bytes: Average node size in bytes
  • min_node_size_bytes: Smallest node size in bytes
  • max_node_size_bytes: Largest node size in bytes
  • avg_entries_per_node: Average number of entries per node

§Level-Based Statistics

  • nodes_per_level: Count of nodes at each level
  • avg_node_size_per_level: Average node size at each level
  • avg_entries_per_level: Average entries per node at each level
  • min_entries_per_level: Minimum entries at each level
  • max_entries_per_level: Maximum entries at each level

§Fanout and Fill Factor

  • avg_fanout: Average number of children per internal node
  • min_fanout: Minimum fanout value
  • max_fanout: Maximum fanout value
  • avg_fill_factor: Average fill factor (entries / max_chunk_size)
  • avg_leaf_fill_factor: Average fill factor for leaf nodes
  • avg_internal_fill_factor: Average fill factor for internal nodes

§Key and Value Sizes

  • avg_key_size_bytes: Average key size in bytes
  • avg_value_size_bytes: Average value size in bytes
  • min_key_size_bytes: Smallest key size
  • max_key_size_bytes: Largest key size
  • min_value_size_bytes: Smallest value size
  • max_value_size_bytes: Largest value size
  • total_keys_size_bytes: Total size of all keys
  • total_values_size_bytes: Total size of all values

§Example

use prolly::{Config, MemStore, Prolly};

let store = MemStore::new();
let prolly = Prolly::new(store, Config::default());
let mut tree = prolly.create();

// Build a tree
for i in 0..100 {
    let key = format!("key_{}", i).into_bytes();
    let val = format!("value_{}", i).into_bytes();
    tree = prolly.put(&tree, key, val).unwrap();
}

// Collect statistics
let stats = prolly.collect_stats(&tree).unwrap();

println!("Tree has {} nodes at height {}", stats.num_nodes, stats.tree_height);
println!("Average fill factor: {:.2}%", stats.avg_fill_factor * 100.0);

Fields§

§num_nodes: usize§num_leaves: usize§num_internal_nodes: usize§tree_height: u8§total_key_value_pairs: usize§total_tree_size_bytes: usize§avg_node_size_bytes: f64§min_node_size_bytes: usize§max_node_size_bytes: usize§avg_entries_per_node: f64§nodes_per_level: BTreeMap<u8, usize>§avg_node_size_per_level: BTreeMap<u8, f64>§avg_entries_per_level: BTreeMap<u8, f64>§min_entries_per_level: BTreeMap<u8, usize>§max_entries_per_level: BTreeMap<u8, usize>§avg_fanout: f64§min_fanout: usize§max_fanout: usize§avg_fill_factor: f64§avg_leaf_fill_factor: f64§avg_internal_fill_factor: f64§avg_key_size_bytes: f64§avg_value_size_bytes: f64§min_key_size_bytes: usize§max_key_size_bytes: usize§min_value_size_bytes: usize§max_value_size_bytes: usize§total_keys_size_bytes: usize§total_values_size_bytes: usize

Implementations§

Source§

impl TreeStats

Source

pub fn new() -> Self

Create a new TreeStats with zero values

All counters are initialized to zero, and min values are set to usize::MAX (they will be reset to 0 for empty trees during finalization).

§Example
use prolly::TreeStats;

let stats = TreeStats::new();
assert_eq!(stats.num_nodes, 0);
assert_eq!(stats.tree_height, 0);
Source§

impl TreeStats

Source

pub fn accumulate(&mut self, node: &Node)

Accumulate statistics from a single node

Updates all relevant counters, min/max values, and level-based statistics based on the provided node. This method is called during tree traversal for each visited node.

After accumulating all nodes, call finalize to compute derived metrics like averages.

§Arguments
  • node - The node to accumulate statistics from
§Example
use prolly::{TreeStats, Node};

let mut stats = TreeStats::new();
let node = Node::builder()
    .keys(vec![b"key".to_vec()])
    .vals(vec![b"value".to_vec()])
    .leaf(true)
    .level(0)
    .build();

stats.accumulate(&node);
assert_eq!(stats.num_nodes, 1);
assert_eq!(stats.num_leaves, 1);
Source

pub fn finalize(&mut self)

Finalize statistics by calculating all derived metrics

This method should be called after all nodes have been accumulated. It calculates averages (node size, entries, fanout, fill factors, key/value sizes) and handles edge cases like division by zero.

For empty trees, min values are reset to 0.

§Example
use prolly::{TreeStats, Node};

let mut stats = TreeStats::new();
let node = Node::builder()
    .keys(vec![b"key".to_vec()])
    .vals(vec![b"value".to_vec()])
    .leaf(true)
    .level(0)
    .max_chunk_size(10)
    .build();

stats.accumulate(&node);
stats.finalize();

assert!(stats.avg_node_size_bytes > 0.0);
assert_eq!(stats.avg_fill_factor, 0.1); // 1 entry / 10 max
Source

pub fn diff(&self, other: &TreeStats) -> StatsDiff

Compute the difference between two statistics objects

Returns a StatsDiff object containing the difference for each numeric metric. Positive values indicate an increase, negative values indicate a decrease.

§Arguments
  • other - The statistics object to compare against (subtracted from self)
§Returns

A StatsDiff object with differences for all metrics

Source

pub fn percentage_change(&self, other: &TreeStats) -> StatsPercentageChange

Compute percentage changes between two statistics objects

Returns a StatsPercentageChange object containing the percentage change for each metric. Percentage change is calculated as: ((self - other) / other) * 100 Returns 0.0 for metrics where the base value (other) is zero.

§Arguments
  • other - The baseline statistics object to compare against
§Returns

A StatsPercentageChange object with percentage changes for all metrics

Source

pub fn add_node(&mut self, node: &Node, node_size_bytes: usize)

Update statistics after adding a node

This method incrementally updates statistics when a new node is added to the tree. It updates all relevant counters, min/max values, and totals. After calling this method, you should call finalize() to recalculate derived metrics (averages).

§Arguments
  • node - The node being added
  • node_size_bytes - The serialized size of the node in bytes
Source

pub fn remove_node(&mut self, node: &Node, node_size_bytes: usize)

Update statistics after removing a node

This method incrementally updates statistics when a node is removed from the tree. It decrements all relevant counters and updates totals. Note that min/max values cannot be accurately updated without a full traversal, so they are left unchanged. After calling this method, you should call finalize() to recalculate derived metrics.

§Arguments
  • node - The node being removed
  • node_size_bytes - The serialized size of the node in bytes
Source

pub fn update_node( &mut self, old_node: &Node, new_node: &Node, old_size: usize, new_size: usize, )

Update statistics after modifying a node

This method incrementally updates statistics when a node is modified in place. It adjusts size totals and entry counts if they changed. Min/max values are updated if the new values exceed the current bounds. After calling this method, you should call finalize() to recalculate derived metrics.

§Arguments
  • old_node - The node before modification
  • new_node - The node after modification
  • old_size - The serialized size of the old node in bytes
  • new_size - The serialized size of the new node in bytes
Source

pub fn validate<S: Store>( &self, prolly: &Prolly<S>, tree: &Tree, ) -> Result<bool, Error>

Validate that incremental statistics match full collection

This method collects fresh statistics from the tree and compares them with the current statistics object. Returns true if they are equal, false otherwise. This is useful for verifying that incremental updates have been applied correctly.

§Arguments
  • prolly - The Prolly instance to use for collecting statistics
  • tree - The tree to validate against
§Returns
  • Ok(true) - Statistics match
  • Ok(false) - Statistics do not match
  • Err(Error) - On storage or deserialization errors

Trait Implementations§

Source§

impl Clone for TreeStats

Source§

fn clone(&self) -> TreeStats

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for TreeStats

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for TreeStats

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for TreeStats

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for TreeStats

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for TreeStats

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for TreeStats

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.