Skip to content

Commit 1a4a122

Browse files
committed
Added a hashmap to improve lookup efficiency against the index list
1 parent b1c147e commit 1a4a122

File tree

1 file changed

+30
-19
lines changed
  • crates/bitwarden-collections/src

1 file changed

+30
-19
lines changed

crates/bitwarden-collections/src/tree.rs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ impl TreeNode {
7272
#[allow(missing_docs)]
7373
pub struct Tree<T: TreeItem> {
7474
pub nodes: Vec<TreeNode>,
75-
pub items: Vec<TreeIndex<T>>,
75+
pub items: HashMap<Uuid, TreeIndex<T>>,
7676
path_to_node: HashMap<Vec<String>, usize>,
7777
}
7878

@@ -81,7 +81,7 @@ impl<T: TreeItem> Tree<T> {
8181
pub fn from_items(items: Vec<T>) -> Self {
8282
let mut tree = Tree {
8383
nodes: Vec::new(),
84-
items: Vec::new(),
84+
items: HashMap::new(),
8585
path_to_node: HashMap::new(),
8686
};
8787

@@ -95,8 +95,7 @@ impl<T: TreeItem> Tree<T> {
9595
// add items
9696
for (index, item) in sorted_items.iter().enumerate() {
9797
let tree_index = TreeIndex::new(index, item);
98-
tree.items.push(tree_index.clone());
99-
98+
tree.items.insert(item.id(), tree_index.clone());
10099
tree.add_item(tree_index);
101100
}
102101

@@ -118,39 +117,51 @@ impl<T: TreeItem> Tree<T> {
118117
self.nodes.push(node);
119118
}
120119

121-
#[allow(missing_docs)]
120+
///
121+
/// Returns an optional node item for a given tree item id.
122+
///
123+
/// This contains the item, its children (or an empty vector), and its parent (if it has one)
122124
pub fn get_item_by_id(&self, tree_item_id: Uuid) -> Option<NodeItem<T>> {
123-
let item = self.items.iter().find(|i| i.data.id() == tree_item_id);
125+
let item = self.items.get(&tree_item_id);
124126

125127
if let Some(item) = item {
126128
let node = self.nodes.get(item.id)?;
127129

128130
// Get the parent if it exists
129-
let parent = node.parent_idx.and_then(|pid| self.nodes.get(pid));
130-
131-
// Get all children nodes
132-
let children: Vec<&TreeNode> = node
131+
let parent = node
132+
.parent_idx
133+
.and_then(|pid| self.nodes.get(pid))
134+
.and_then(|p| self.items.get(&p.item_id))
135+
.map(|p| p.data.clone());
136+
137+
// Get any children
138+
let children: Vec<T> = node
133139
.children_idx
134140
.iter()
135141
.filter_map(|&child_id| self.nodes.get(child_id))
136-
.collect();
137-
138-
// Get corresponding items
139-
let parent_item = parent.and_then(|p| self.items.get(p.id));
140-
let children_items: Vec<&TreeIndex<T>> = children
141-
.iter()
142-
.filter_map(|child| self.items.get(child.id))
142+
.filter_map(|child| self.items.get(&child.item_id))
143+
.map(|i| i.data.clone())
143144
.collect();
144145

145146
return Some(NodeItem {
146147
item: item.data.clone(),
147-
parent: parent_item.map(|p| p.data.clone()),
148-
children: children_items.iter().map(|i| i.data.clone()).collect(),
148+
parent,
149+
children,
149150
});
150151
}
151152

152153
None
153154
}
155+
156+
///
157+
/// Returns the list of root nodes with their children
158+
pub fn get_root_items(&self) -> Vec<NodeItem<T>> {
159+
self.nodes
160+
.iter()
161+
.filter(|n| n.parent_idx.is_none())
162+
.filter_map(|n| self.get_item_by_id(n.item_id))
163+
.collect()
164+
}
154165
}
155166

156167
#[cfg(test)]

0 commit comments

Comments
 (0)