Skip to content

Commit

Permalink
chore: remove snapshot counters
Browse files Browse the repository at this point in the history
  • Loading branch information
arriqaaq authored Mar 18, 2024
1 parent 07fa2f5 commit 334551a
Show file tree
Hide file tree
Showing 6 changed files with 18 additions and 164 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "vart"
publish = true
version = "0.1.1"
version = "0.1.2"
edition = "2021"
license = "Apache-2.0"
readme = "README.md"
Expand Down
100 changes: 11 additions & 89 deletions src/art.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
use core::panic;
use std::cmp::min;
use std::ops::RangeBounds;
use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;

use hashbrown::HashSet;

use crate::iter::{Iter, Range};
use crate::node::{FlatNode, Node256, Node48, NodeTrait, TwigNode, Version};
use crate::snapshot::Snapshot;
Expand All @@ -26,9 +23,6 @@ const NODE48MAX: usize = 48;
// Minimum and maximum number of children for Node256
const NODE256MIN: usize = NODE48MAX + 1;

// Maximum number of active snapshots
pub const DEFAULT_MAX_ACTIVE_SNAPSHOTS: u64 = 10000;

/// A struct representing a node in an Adaptive Radix Trie.
///
/// The `Node` struct encapsulates a single node within the adaptive radix trie structure.
Expand Down Expand Up @@ -877,8 +871,7 @@ impl<P: KeyTrait + Clone, V: Clone> Node<P, V> {
/// A struct representing an Adaptive Radix Trie.
///
/// The `Tree` struct encompasses the entire adaptive radix trie data structure.
/// It manages the root node of the tree, maintains snapshots of the tree's state,
/// and keeps track of various properties related to snapshot management.
/// It manages the root node of the tree.
///
/// # Type Parameters
///
Expand All @@ -888,19 +881,10 @@ impl<P: KeyTrait + Clone, V: Clone> Node<P, V> {
/// # Fields
///
/// - `root`: An optional shared reference (using `Rc`) to the root node of the tree.
/// - `snapshots`: A `HashSet` storing snapshots of the tree's state, mapped by snapshot IDs.
/// - `max_snapshot_id`: An `AtomicU64` representing the maximum snapshot ID assigned.
/// - `max_active_snapshots`: The maximum number of active snapshots allowed.
///
pub struct Tree<P: KeyTrait, V: Clone> {
/// An optional shared reference to the root node of the tree.
pub(crate) root: Option<Arc<Node<P, V>>>,
/// A mapping of snapshot IDs to their corresponding snapshots.
pub(crate) snapshots: HashSet<u64>,
/// An atomic value indicating the maximum snapshot ID assigned.
pub(crate) max_snapshot_id: AtomicU64,
/// The maximum number of active snapshots allowed.
pub(crate) max_active_snapshots: u64,
/// A flag indicating whether the tree is closed.
pub(crate) closed: bool,
}
Expand Down Expand Up @@ -951,17 +935,10 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {
pub fn new() -> Self {
Tree {
root: None,
max_snapshot_id: AtomicU64::new(0),
snapshots: HashSet::new(),
max_active_snapshots: DEFAULT_MAX_ACTIVE_SNAPSHOTS,
closed: false,
}
}

pub fn set_max_active_snapshots(&mut self, max_active_snapshots: u64) {
self.max_active_snapshots = max_active_snapshots;
}

/// Inserts a new key-value pair with the specified version into the Trie.
///
/// This function inserts a new key-value pair into the Trie. If the key already exists,
Expand Down Expand Up @@ -991,7 +968,7 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {
ts: u64,
) -> Result<Option<V>, TrieError> {
// Check if the tree is already closed
self.is_closed()?;
self.check_if_closed()?;

let (new_root, old_node) = match &self.root {
None => {
Expand Down Expand Up @@ -1037,7 +1014,7 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {

pub fn bulk_insert(&mut self, kv_pairs: &[KV<P, V>]) -> Result<(), TrieError> {
// Check if the tree is already closed
self.is_closed()?;
self.check_if_closed()?;

let curr_version = self.version();
let mut new_version = 0;
Expand Down Expand Up @@ -1106,7 +1083,7 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {

pub fn remove(&mut self, key: &P) -> Result<bool, TrieError> {
// Check if the tree is already closed
self.is_closed()?;
self.check_if_closed()?;

let (new_root, is_deleted) = match &self.root {
None => (None, false),
Expand All @@ -1130,7 +1107,7 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {

pub fn get(&self, key: &P, version: u64) -> Result<(P, V, u64, u64), TrieError> {
// Check if the tree is already closed
self.is_closed()?;
self.check_if_closed()?;

if self.root.is_none() {
return Err(TrieError::Other("cannot read from empty tree".to_string()));
Expand Down Expand Up @@ -1171,66 +1148,17 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {
/// Returns a `Result` containing the `Snapshot` if the snapshot is created successfully,
/// or an `Err` with an appropriate error message if creation fails.
///
pub fn create_snapshot(&mut self) -> Result<Snapshot<P, V>, TrieError> {
pub fn create_snapshot(&self) -> Result<Snapshot<P, V>, TrieError> {
// Check if the tree is already closed
self.is_closed()?;

if self.snapshots.len() >= self.max_active_snapshots as usize {
return Err(TrieError::Other(
"max number of snapshots reached".to_string(),
));
}

// Increment the snapshot ID atomically
let new_snapshot_id = self.max_snapshot_id.fetch_add(1, Ordering::SeqCst);
self.snapshots.insert(new_snapshot_id);
self.check_if_closed()?;

let root = self.root.as_ref().cloned();
let version = self.root.as_ref().map_or(1, |root| root.version() + 1);
let new_snapshot = Snapshot::new(new_snapshot_id, root, version);
let new_snapshot = Snapshot::new(root, version);

Ok(new_snapshot)
}

/// Closes a snapshot and removes it from the list of active snapshots.
///
/// This function takes a `snapshot_id` as an argument and closes the corresponding snapshot.
/// If the snapshot exists, it is removed from the active snapshots list. If the snapshot is not
/// found, an `Err` is returned with a `TrieError::SnapshotNotFound` variant.
///
/// # Arguments
///
/// * `snapshot_id` - The ID of the snapshot to be closed and removed.
///
/// # Returns
///
/// Returns `Ok(())` if the snapshot is successfully closed and removed. Returns an `Err`
/// with `TrieError::SnapshotNotFound` if the snapshot with the given ID is not found.
///
pub fn close_snapshot(&mut self, snapshot_id: u64) -> Result<(), TrieError> {
// Check if the tree is already closed
self.is_closed()?;

if self.snapshots.remove(&snapshot_id) {
Ok(())
} else {
Err(TrieError::SnapshotNotFound)
}
}

/// Returns the count of active snapshots.
///
/// This function returns the number of currently active snapshots in the Trie.
///
/// # Returns
///
/// Returns a `Result` containing the count of active snapshots if successful, or an `Err`
/// if there is an issue retrieving the snapshot count.
///
pub fn snapshot_count(&self) -> usize {
self.snapshots.len()
}

/// Creates an iterator over the Trie's key-value pairs.
///
/// This function creates and returns an iterator that can be used to traverse the key-value pairs
Expand Down Expand Up @@ -1275,24 +1203,18 @@ impl<P: KeyTrait, V: Clone> Tree<P, V> {
Range::new(root, range)
}

fn is_closed(&self) -> Result<(), TrieError> {
fn check_if_closed(&self) -> Result<(), TrieError> {
if self.closed {
return Err(TrieError::SnapshotAlreadyClosed);
return Err(TrieError::TreeAlreadyClosed);
}
Ok(())
}

/// Closes the tree, preventing further modifications, and releases associated resources.
pub fn close(&mut self) -> Result<(), TrieError> {
// Check if the tree is already closed
self.is_closed()?;

// Check if there are any active readers for the snapshot
if self.snapshot_count() > 0 {
return Err(TrieError::SnapshotNotClosed);
}
self.check_if_closed()?;

// Mark the snapshot as closed
self.closed = true;

Ok(())
Expand Down
7 changes: 2 additions & 5 deletions src/iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@ use crate::KeyTrait;
// TODO: need to add more tests for snapshot readers
/// A structure representing a pointer for iterating over the Trie's key-value pairs.
pub struct IterationPointer<P: KeyTrait, V: Clone> {
#[allow(dead_code)]
pub(crate) id: u64,
root: Arc<Node<P, V>>,
}

Expand All @@ -19,10 +17,9 @@ impl<P: KeyTrait, V: Clone> IterationPointer<P, V> {
/// # Arguments
///
/// * `root` - The root node of the Trie.
/// * `id` - The ID of the snapshot.
///
pub fn new(root: Arc<Node<P, V>>, id: u64) -> IterationPointer<P, V> {
IterationPointer { id, root }
pub fn new(root: Arc<Node<P, V>>) -> IterationPointer<P, V> {
IterationPointer { root }
}

/// Returns an iterator over the key-value pairs within the Trie.
Expand Down
6 changes: 0 additions & 6 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,11 +387,9 @@ pub enum TrieError {
IllegalArguments,
NotFound,
KeyNotFound,
SnapshotNotFound,
SnapshotEmpty,
SnapshotNotClosed,
SnapshotAlreadyClosed,
SnapshotReadersNotClosed,
TreeAlreadyClosed,
FixedSizeKeyLengthExceeded,
Other(String),
Expand All @@ -406,12 +404,8 @@ impl fmt::Display for TrieError {
TrieError::IllegalArguments => write!(f, "Illegal arguments"),
TrieError::NotFound => write!(f, "Not found"),
TrieError::KeyNotFound => write!(f, "Key not found"),
TrieError::SnapshotNotFound => write!(f, "Snapshot not found"),
TrieError::SnapshotNotClosed => write!(f, "Snapshot not closed"),
TrieError::SnapshotAlreadyClosed => write!(f, "Snapshot already closed"),
TrieError::SnapshotReadersNotClosed => {
write!(f, "Readers in the snapshot are not closed")
}
TrieError::TreeAlreadyClosed => write!(f, "Tree already closed"),
TrieError::Other(ref message) => write!(f, "Other error: {}", message),
TrieError::SnapshotEmpty => write!(f, "Snapshot is empty"),
Expand Down
Loading

0 comments on commit 334551a

Please sign in to comment.