##// END OF EJS Templates
rust-nodemap: mutable NodeTree data structure...
Georges Racinet -
r44646:a1933145 default
parent child Browse files
Show More
@@ -191,16 +191,31 b' impl fmt::Debug for Block {'
191 }
191 }
192 }
192 }
193
193
194 /// A 16-radix tree with the root block at the end
194 /// A mutable 16-radix tree with the root block logically at the end
195 ///
196 /// Because of the append only nature of our node trees, we need to
197 /// keep the original untouched and store new blocks separately.
198 ///
199 /// The mutable root `Block` is kept apart so that we don't have to rebump
200 /// it on each insertion.
195 pub struct NodeTree {
201 pub struct NodeTree {
196 readonly: Box<dyn Deref<Target = [Block]> + Send>,
202 readonly: Box<dyn Deref<Target = [Block]> + Send>,
203 growable: Vec<Block>,
204 root: Block,
197 }
205 }
198
206
199 impl Index<usize> for NodeTree {
207 impl Index<usize> for NodeTree {
200 type Output = Block;
208 type Output = Block;
201
209
202 fn index(&self, i: usize) -> &Block {
210 fn index(&self, i: usize) -> &Block {
203 &self.readonly[i]
211 let ro_len = self.readonly.len();
212 if i < ro_len {
213 &self.readonly[i]
214 } else if i == ro_len + self.growable.len() {
215 &self.root
216 } else {
217 &self.growable[i - ro_len]
218 }
204 }
219 }
205 }
220 }
206
221
@@ -222,12 +237,32 b" fn has_prefix_or_none<'p>("
222 }
237 }
223
238
224 impl NodeTree {
239 impl NodeTree {
225 fn len(&self) -> usize {
240 /// Initiate a NodeTree from an immutable slice-like of `Block`
226 self.readonly.len()
241 ///
242 /// We keep `readonly` and clone its root block if it isn't empty.
243 fn new(readonly: Box<dyn Deref<Target = [Block]> + Send>) -> Self {
244 let root = readonly
245 .last()
246 .map(|b| b.clone())
247 .unwrap_or_else(|| Block::new());
248 NodeTree {
249 readonly: readonly,
250 growable: Vec::new(),
251 root: root,
252 }
227 }
253 }
228
254
255 /// Total number of blocks
256 fn len(&self) -> usize {
257 self.readonly.len() + self.growable.len() + 1
258 }
259
260 /// Implemented for completeness
261 ///
262 /// A `NodeTree` always has at least the mutable root block.
263 #[allow(dead_code)]
229 fn is_empty(&self) -> bool {
264 fn is_empty(&self) -> bool {
230 self.len() == 0
265 false
231 }
266 }
232
267
233 /// Main working method for `NodeTree` searches
268 /// Main working method for `NodeTree` searches
@@ -237,9 +272,6 b' impl NodeTree {'
237 &self,
272 &self,
238 prefix: NodePrefixRef<'p>,
273 prefix: NodePrefixRef<'p>,
239 ) -> Result<Option<Revision>, NodeMapError> {
274 ) -> Result<Option<Revision>, NodeMapError> {
240 if self.is_empty() {
241 return Ok(None);
242 }
243 let mut visit = self.len() - 1;
275 let mut visit = self.len() - 1;
244 for i in 0..prefix.len() {
276 for i in 0..prefix.len() {
245 let nybble = prefix.get_nybble(i);
277 let nybble = prefix.get_nybble(i);
@@ -255,16 +287,18 b' impl NodeTree {'
255
287
256 impl From<Vec<Block>> for NodeTree {
288 impl From<Vec<Block>> for NodeTree {
257 fn from(vec: Vec<Block>) -> Self {
289 fn from(vec: Vec<Block>) -> Self {
258 NodeTree {
290 Self::new(Box::new(vec))
259 readonly: Box::new(vec),
260 }
261 }
291 }
262 }
292 }
263
293
264 impl fmt::Debug for NodeTree {
294 impl fmt::Debug for NodeTree {
265 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
266 let blocks: &[Block] = &*self.readonly;
296 let readonly: &[Block] = &*self.readonly;
267 write!(f, "readonly: {:?}", blocks)
297 write!(
298 f,
299 "readonly: {:?}, growable: {:?}, root: {:?}",
300 readonly, self.growable, self.root
301 )
268 }
302 }
269 }
303 }
270
304
@@ -365,7 +399,9 b' mod tests {'
365 assert_eq!(
399 assert_eq!(
366 format!("{:?}", nt),
400 format!("{:?}", nt),
367 "readonly: \
401 "readonly: \
368 [{0: Rev(9)}, {0: Rev(0), 1: Rev(9)}, {0: Block(1), 1: Rev(1)}]"
402 [{0: Rev(9)}, {0: Rev(0), 1: Rev(9)}, {0: Block(1), 1: Rev(1)}], \
403 growable: [], \
404 root: {0: Block(1), 1: Rev(1)}",
369 );
405 );
370 }
406 }
371
407
@@ -374,7 +410,7 b' mod tests {'
374 let mut idx: TestIndex = HashMap::new();
410 let mut idx: TestIndex = HashMap::new();
375 pad_insert(&mut idx, 1, "1234deadcafe");
411 pad_insert(&mut idx, 1, "1234deadcafe");
376
412
377 let nt = NodeTree::from(vec![block![1: Rev(1)]]);
413 let nt = NodeTree::from(vec![block! {1: Rev(1)}]);
378 assert_eq!(nt.find_hex(&idx, "1")?, Some(1));
414 assert_eq!(nt.find_hex(&idx, "1")?, Some(1));
379 assert_eq!(nt.find_hex(&idx, "12")?, Some(1));
415 assert_eq!(nt.find_hex(&idx, "12")?, Some(1));
380 assert_eq!(nt.find_hex(&idx, "1234de")?, Some(1));
416 assert_eq!(nt.find_hex(&idx, "1234de")?, Some(1));
@@ -401,4 +437,25 b' mod tests {'
401 assert_eq!(nt.find_hex(&idx, "00"), Ok(Some(0)));
437 assert_eq!(nt.find_hex(&idx, "00"), Ok(Some(0)));
402 assert_eq!(nt.find_hex(&idx, "00a"), Ok(Some(0)));
438 assert_eq!(nt.find_hex(&idx, "00a"), Ok(Some(0)));
403 }
439 }
440
441 #[test]
442 fn test_mutated_find() -> Result<(), NodeMapError> {
443 let mut idx = TestIndex::new();
444 pad_insert(&mut idx, 9, "012");
445 pad_insert(&mut idx, 0, "00a");
446 pad_insert(&mut idx, 2, "cafe");
447 pad_insert(&mut idx, 3, "15");
448 pad_insert(&mut idx, 1, "10");
449
450 let nt = NodeTree {
451 readonly: sample_nodetree().readonly,
452 growable: vec![block![0: Rev(1), 5: Rev(3)]],
453 root: block![0: Block(1), 1:Block(3), 12: Rev(2)],
454 };
455 assert_eq!(nt.find_hex(&idx, "10")?, Some(1));
456 assert_eq!(nt.find_hex(&idx, "c")?, Some(2));
457 assert_eq!(nt.find_hex(&idx, "00")?, Some(0));
458 assert_eq!(nt.find_hex(&idx, "01")?, Some(9));
459 Ok(())
460 }
404 }
461 }
General Comments 0
You need to be logged in to leave comments. Login now