bitstring_trees/
set.rs

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! [`Set`] of bit string prefixes

use core::cmp::Ordering;

use bitstring::BitString;

use crate::tree::{
	DefaultCompare,
	InsertPositionWith,
	Tree,
	TreeProperties,
};

mod hidden {
	use bitstring::BitString;
	use core::marker::PhantomData;

	/// make it public so we can use it in returned types, but don't make it directly accessible
	pub struct TpSet<K: BitString + Clone>(PhantomData<*const K>);
}
use hidden::TpSet;

impl<K: BitString + Clone> TreeProperties for TpSet<K> {
	type Key = K;
	type LeafValue = ();
	type LeafValueComparer = DefaultCompare;
	type Value = ();

	const EMPTY: bool = true;
	const IGNORE_LEAFS: bool = false;
	const LEAF_EMPTY: bool = true;
}

/// Set of bit string prefixes
///
/// Sibling prefixes are automatically merged.
///
/// This is implemented as a [`crate::tree::Tree`] where nodes don't carry
/// values at all, buf leaf nodes represent set membership of the associated
/// key.
#[derive(Clone)]
pub struct Set<K: BitString + Clone> {
	tree: Tree<TpSet<K>>,
}

impl<K: BitString + Clone> Default for Set<K> {
	fn default() -> Self {
		Self::new()
	}
}

impl<K: BitString + Clone + core::fmt::Debug> core::fmt::Debug for Set<K> {
	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
		f.debug_set().entries(self.iter()).finish()
	}
}

impl<K: BitString + Clone> Set<K> {
	/// New (empty) set.
	pub const fn new() -> Self {
		Self { tree: Tree::new() }
	}

	/// Access raw tree of set
	pub fn tree(&self) -> &Tree<TpSet<K>> {
		&self.tree
	}

	/// Insert prefix into set
	pub fn insert(&mut self, key: K) {
		self.tree.set_leaf_value(key, ());
	}

	/// Remove everything covered by prefix from set
	pub fn remove(&mut self, key: K) {
		let mut walk = self.tree.walk_mut();
		walk.goto_insert(&key);
		match walk.current().node() {
			None => (), // empty tree
			Some(node) => {
				match node.get_key().len().cmp(&key.len()) {
					Ordering::Less => {
						// node is a leaf and covers key; need to split and remove key
						// create explicit node with key we want to remove
						walk.insert(key);
						// now remove it
						walk.delete_current();
					},
					Ordering::Equal | Ordering::Greater => {
						// remove subtree
						walk.delete_current();
					},
				}
			},
		}
	}

	/// Whether prefix is (completely) contained in set
	pub fn contains(&self, key: &K) -> bool {
		match self.tree.goto_insert(key) {
			Some(InsertPositionWith::BelowLeaf(_)) => true,
			Some(InsertPositionWith::AlreadyExists(_)) => true,
			Some(InsertPositionWith::ReplaceNode(_)) => false,
			None => false,
		}
	}

	/// Iterate over all contained prefixes
	pub fn iter(&self) -> IterSet<'_, K> {
		IterSet {
			iter: self.tree.iter_leaf(),
		}
	}

	/// Iterate over smallest list of bit strings that cover everything with information whether they are part of the set or not
	pub fn iter_full(&self) -> IterSetFull<'_, K> {
		IterSetFull {
			iter: self.tree.iter_leaf_full(),
		}
	}
}

/// Iterate over all prefixes contained in a set
pub struct IterSet<'s, K: BitString + Clone> {
	iter: super::tree::IterLeaf<'s, TpSet<K>>,
}

impl<'s, K: BitString + Clone> Iterator for IterSet<'s, K> {
	type Item = &'s K;

	fn next(&mut self) -> Option<Self::Item> {
		Some(self.iter.next()?.0.get_key())
	}
}

/// Iterate over smallest list of bit strings that cover everything with information whether they are part of the set or not
pub struct IterSetFull<'s, K: BitString + Clone> {
	iter: super::tree::IterLeafFull<'s, TpSet<K>>,
}

impl<'s, K: BitString + Clone> Iterator for IterSetFull<'s, K> {
	type Item = (K, bool);

	fn next(&mut self) -> Option<Self::Item> {
		let (key, value) = self.iter.next()?;
		Some((key, value.is_some()))
	}
}