1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
use std::collections::HashMap;

use bonsaidb_core::schema::{CollectionName, Schematic};
use nebari::io::any::AnyFile;
use nebari::tree::{AnyTreeRoot, Root, Unversioned, Versioned};

use crate::database::document_tree_name;
#[cfg(any(feature = "encryption", feature = "compression"))]
use crate::storage::TreeVault;
use crate::views::{
    view_document_map_tree_name, view_entries_tree_name, view_invalidated_docs_tree_name,
};

#[derive(Default)]
pub(crate) struct OpenTrees {
    pub trees: Vec<Box<dyn AnyTreeRoot<AnyFile>>>,
    pub trees_index_by_name: HashMap<String, usize>,
}

impl OpenTrees {
    #[cfg_attr(not(feature = "encryption"), allow(unused_mut))]
    #[cfg_attr(feature = "encryption", allow(clippy::unnecessary_wraps))]
    pub fn open_tree<R: Root>(
        &mut self,
        name: &str,
        #[cfg(any(feature = "encryption", feature = "compression"))] vault: Option<TreeVault>,
    ) {
        if !self.trees_index_by_name.contains_key(name) {
            self.trees_index_by_name
                .insert(name.to_string(), self.trees.len());
            let mut tree = R::tree(name.to_string());

            #[cfg(any(feature = "encryption", feature = "compression"))]
            if let Some(vault) = vault {
                tree = tree.with_vault(vault);
            }

            self.trees.push(Box::new(tree));
        }
    }

    #[allow(clippy::needless_pass_by_value)]
    pub fn open_trees_for_document_change(
        &mut self,
        collection: &CollectionName,
        schema: &Schematic,
        #[cfg(any(feature = "encryption", feature = "compression"))] vault: Option<TreeVault>,
    ) {
        self.open_tree::<Versioned>(
            &document_tree_name(collection),
            #[cfg(any(feature = "encryption", feature = "compression"))]
            vault.clone(),
        );

        for view in schema.views_in_collection(collection) {
            let view_name = view.view_name();
            if view.update_policy().is_eager() {
                self.open_tree::<Unversioned>(
                    &view_document_map_tree_name(&view_name),
                    #[cfg(any(feature = "encryption", feature = "compression"))]
                    vault.clone(),
                );
                self.open_tree::<Unversioned>(
                    &view_entries_tree_name(&view_name),
                    #[cfg(any(feature = "encryption", feature = "compression"))]
                    vault.clone(),
                );
            } else {
                self.open_tree::<Unversioned>(
                    &view_invalidated_docs_tree_name(&view_name),
                    #[cfg(any(feature = "encryption", feature = "compression"))]
                    vault.clone(),
                );
            }
        }
    }
}