//! An example on how to use `nebari::tree`, the low-level single-tree database //! layer. For most users, the `nebari::Roots` type should be preferred. use nebari::{ io::{fs::StdFile, memory::MemoryFile, ManagedFile}, tree::{ScanEvaluation, State, TreeFile, Unversioned, Versioned}, ArcBytes, Context, Error, }; fn main() -> Result<(), Error> { // At its core, Nebari operates on TreeFiles. Each TreeFile is defined by // its Root -- the two Roots included with Nebari are the VersionedTreeRoot // and UnversionedTreeRoot. As you may guess from their names, the different // tree roots control whether full revision information is stored. // // To begin, let's open up a file without versioning on the filesystem: let mut unversioned_tree = TreeFile::::write( "unversioned-tree.nebari", State::default(), &Context::default(), None, )?; // We can use this filesystem-backed tree to do common tree operations. tree_basics(&mut unversioned_tree)?; // Or we could do the same thing, but this time using a memory-backed file. // Note: this isn't recommended to be used in production, but it can be // helpful in CI environments. let mut unversioned_memory_tree = TreeFile::::write( "unversioned-tree.nebari", State::default(), &Context::default(), None, )?; tree_basics(&mut unversioned_memory_tree)?; // We can also use the VersionedTreeRoot to be able to view full revision history in a tree. let mut versioned_tree = TreeFile::::write( "versioned-tree.nebari", State::default(), &Context::default(), None, )?; tree_basics(&mut versioned_tree)?; versioned_tree.scan_sequences( .., true, false, &mut |_key| ScanEvaluation::ReadData, &mut |key, data| { println!( "Key {:?} contained {:?} at sequence {:?}. Previous sequence: {:?}", key.key, data, key.sequence, key.last_sequence ); Ok(()) }, )?; Ok(()) } fn tree_basics( tree: &mut TreeFile, ) -> Result<(), Error> { // Insert a few key-value pairs. tree.set(None, ArcBytes::from(b"a key"), ArcBytes::from(b"a value"))?; tree.set(None, ArcBytes::from(b"b key"), ArcBytes::from(b"b value"))?; // Retrieve a value. let value = tree.get(b"a key", false)?.unwrap(); assert_eq!(value, b"a value"); // Scan for values tree.scan( &(..), true, false, &mut |_, _, _| ScanEvaluation::ReadData, &mut |_key, _index| ScanEvaluation::ReadData, &mut |key, _index, value| { println!("Found key {:?} with value {:?}", key, value); Ok(()) }, )?; // Replace the value for "a key" tree.set( None, ArcBytes::from(b"a key"), ArcBytes::from(b"a new value"), )?; let updated_value = tree.get(b"a key", false)?.unwrap(); assert_eq!(updated_value, b"a new value"); Ok(()) }