Token for tracking when an insert has been durably fsynced to disk
DurabilityToken is returned from RotorTree::insert() and insert_many() to allow the caller to wait until the corresponding WAL entry has been fsynced to disk.
Blocks the current thread until the WAL entry for this insert has been fsynced to disk.
pub fn wait(&self)
Behavior:
Blocks until the background flush thread (if using FlushPolicy::Interval) completes an fsync that includes this entry’s sequence number
Returns immediately if already fsynced
Safe to call from multiple threads
Example:
let (root, token) = tree.insert([42u8; 32])?;// Do other work...// Wait for durabilitytoken.wait();// Now guaranteed: insert is durable even if process crashes
use rotortree::RotorTree;let tree = RotorTree::open(hasher, config)?;// Insert and get tokenlet (root, token) = tree.insert(leaf)?;// Wait for durabilitytoken.wait();// Safe to acknowledge to userOk(root)
// Insert many leaveslet leaves = vec![[1u8; 32]; 10_000];let (root, token) = tree.insert_many(&leaves)?;// Wait for entire batch to be durabletoken.wait();println!("All 10,000 leaves are durable");
use std::thread;use std::time::Duration;let (root, token) = tree.insert(leaf)?;// Poll for durabilityloop { if token.is_durable() { println!("Insert is now durable"); break; } // Do other work thread::sleep(Duration::from_millis(1));}
use std::collections::VecDeque;let mut tokens = VecDeque::new();// Insert many entriesfor leaf in leaves { let (_, token) = tree.insert(leaf)?; tokens.push_back(token);}// Wait for all to be durablefor token in tokens { token.wait();}println!("All inserts durable");
// SLOW: Serial fsync for each insertfor leaf in &leaves { let (_, token) = tree.insert(*leaf)?; token.wait(); // Blocks for fsync on each insert}// Throughput: ~100-1000 inserts/sec (limited by fsync latency)
// FAST: Amortize fsync over many insertslet mut tokens = vec![];for leaf in &leaves { let (_, token) = tree.insert(*leaf)?; tokens.push(token);}// Wait for batch flushfor token in tokens { token.wait();}// Throughput: ~1M+ inserts/sec (limited by CPU, not fsync)
Background thread periodically fsyncs. Tokens wait for the next flush that includes their sequence number.
let config = RotorTreeConfig { flush_policy: FlushPolicy::Interval(Duration::from_millis(10)), // ...};let tree = RotorTree::open(hasher, config)?;let (_, token) = tree.insert(leaf)?;// Waits up to 10ms for next background flushtoken.wait();
No automatic flushing. Tokens wait indefinitely until tree.flush() is called.
let config = RotorTreeConfig { flush_policy: FlushPolicy::Manual, // ...};let tree = RotorTree::open(hasher, config)?;let (_, token) = tree.insert(leaf)?;// This would block forever without a flush:// token.wait();// Must manually flush:tree.flush()?;// Now token unblocks:token.wait(); // Returns immediately