Show More
@@ -274,6 +274,7 b' pub struct NodeTree {' | |||||
274 | readonly: Box<dyn Deref<Target = [Block]> + Send>, |
|
274 | readonly: Box<dyn Deref<Target = [Block]> + Send>, | |
275 | growable: Vec<Block>, |
|
275 | growable: Vec<Block>, | |
276 | root: Block, |
|
276 | root: Block, | |
|
277 | masked_inner_blocks: usize, | |||
277 | } |
|
278 | } | |
278 |
|
279 | |||
279 | impl Index<usize> for NodeTree { |
|
280 | impl Index<usize> for NodeTree { | |
@@ -350,6 +351,7 b' impl NodeTree {' | |||||
350 | readonly: readonly, |
|
351 | readonly: readonly, | |
351 | growable: Vec::new(), |
|
352 | growable: Vec::new(), | |
352 | root: root, |
|
353 | root: root, | |
|
354 | masked_inner_blocks: 0, | |||
353 | } |
|
355 | } | |
354 | } |
|
356 | } | |
355 |
|
357 | |||
@@ -483,6 +485,7 b' impl NodeTree {' | |||||
483 | let ro_len = ro_blocks.len(); |
|
485 | let ro_len = ro_blocks.len(); | |
484 | let glen = self.growable.len(); |
|
486 | let glen = self.growable.len(); | |
485 | if idx < ro_len { |
|
487 | if idx < ro_len { | |
|
488 | self.masked_inner_blocks += 1; | |||
486 | // TODO OPTIM I think this makes two copies |
|
489 | // TODO OPTIM I think this makes two copies | |
487 | self.growable.push(ro_blocks[idx].clone()); |
|
490 | self.growable.push(ro_blocks[idx].clone()); | |
488 | (glen + ro_len, &mut self.growable[glen], glen + 1) |
|
491 | (glen + ro_len, &mut self.growable[glen], glen + 1) | |
@@ -571,6 +574,22 b' impl NodeTree {' | |||||
571 | } |
|
574 | } | |
572 | Ok(()) |
|
575 | Ok(()) | |
573 | } |
|
576 | } | |
|
577 | ||||
|
578 | /// Return the number of blocks in the readonly part that are currently | |||
|
579 | /// masked in the mutable part. | |||
|
580 | /// | |||
|
581 | /// The `NodeTree` structure has no efficient way to know how many blocks | |||
|
582 | /// are already unreachable in the readonly part. | |||
|
583 | pub fn masked_readonly_blocks(&self) -> usize { | |||
|
584 | if let Some(readonly_root) = self.readonly.last() { | |||
|
585 | if readonly_root == &self.root { | |||
|
586 | return 0; | |||
|
587 | } | |||
|
588 | } else { | |||
|
589 | return 0; | |||
|
590 | } | |||
|
591 | self.masked_inner_blocks + 1 | |||
|
592 | } | |||
574 | } |
|
593 | } | |
575 |
|
594 | |||
576 | pub struct NodeTreeBytes { |
|
595 | pub struct NodeTreeBytes { | |
@@ -853,6 +872,7 b' mod tests {' | |||||
853 | readonly: sample_nodetree().readonly, |
|
872 | readonly: sample_nodetree().readonly, | |
854 | growable: vec![block![0: Rev(1), 5: Rev(3)]], |
|
873 | growable: vec![block![0: Rev(1), 5: Rev(3)]], | |
855 | root: block![0: Block(1), 1:Block(3), 12: Rev(2)], |
|
874 | root: block![0: Block(1), 1:Block(3), 12: Rev(2)], | |
|
875 | masked_inner_blocks: 1, | |||
856 | }; |
|
876 | }; | |
857 | assert_eq!(nt.find_hex(&idx, "10")?, Some(1)); |
|
877 | assert_eq!(nt.find_hex(&idx, "10")?, Some(1)); | |
858 | assert_eq!(nt.find_hex(&idx, "c")?, Some(2)); |
|
878 | assert_eq!(nt.find_hex(&idx, "c")?, Some(2)); | |
@@ -861,6 +881,7 b' mod tests {' | |||||
861 | assert_eq!(nt.find_hex(&idx, "000")?, Some(NULL_REVISION)); |
|
881 | assert_eq!(nt.find_hex(&idx, "000")?, Some(NULL_REVISION)); | |
862 | assert_eq!(nt.unique_prefix_len_hex(&idx, "000")?, Some(3)); |
|
882 | assert_eq!(nt.unique_prefix_len_hex(&idx, "000")?, Some(3)); | |
863 | assert_eq!(nt.find_hex(&idx, "01")?, Some(9)); |
|
883 | assert_eq!(nt.find_hex(&idx, "01")?, Some(9)); | |
|
884 | assert_eq!(nt.masked_readonly_blocks(), 2); | |||
864 | Ok(()) |
|
885 | Ok(()) | |
865 | } |
|
886 | } | |
866 |
|
887 | |||
@@ -950,6 +971,8 b' mod tests {' | |||||
950 | assert_eq!(idx.find_hex("1a345")?, Some(3)); |
|
971 | assert_eq!(idx.find_hex("1a345")?, Some(3)); | |
951 | assert_eq!(idx.find_hex("1a341")?, None); |
|
972 | assert_eq!(idx.find_hex("1a341")?, None); | |
952 |
|
973 | |||
|
974 | // there's no readonly block to mask | |||
|
975 | assert_eq!(idx.nt.masked_readonly_blocks(), 0); | |||
953 | Ok(()) |
|
976 | Ok(()) | |
954 | } |
|
977 | } | |
955 |
|
978 | |||
@@ -1011,6 +1034,8 b' mod tests {' | |||||
1011 | assert_eq!(idx.find_hex("1235")?, Some(1)); |
|
1034 | assert_eq!(idx.find_hex("1235")?, Some(1)); | |
1012 | assert_eq!(idx.find_hex("131")?, Some(2)); |
|
1035 | assert_eq!(idx.find_hex("131")?, Some(2)); | |
1013 | assert_eq!(idx.find_hex("cafe")?, Some(3)); |
|
1036 | assert_eq!(idx.find_hex("cafe")?, Some(3)); | |
|
1037 | // we did not add anything since init from readonly | |||
|
1038 | assert_eq!(idx.nt.masked_readonly_blocks(), 0); | |||
1014 |
|
1039 | |||
1015 | idx.insert(4, "123A")?; |
|
1040 | idx.insert(4, "123A")?; | |
1016 | assert_eq!(idx.find_hex("1234")?, Some(0)); |
|
1041 | assert_eq!(idx.find_hex("1234")?, Some(0)); | |
@@ -1018,12 +1043,18 b' mod tests {' | |||||
1018 | assert_eq!(idx.find_hex("131")?, Some(2)); |
|
1043 | assert_eq!(idx.find_hex("131")?, Some(2)); | |
1019 | assert_eq!(idx.find_hex("cafe")?, Some(3)); |
|
1044 | assert_eq!(idx.find_hex("cafe")?, Some(3)); | |
1020 | assert_eq!(idx.find_hex("123A")?, Some(4)); |
|
1045 | assert_eq!(idx.find_hex("123A")?, Some(4)); | |
|
1046 | // we masked blocks for all prefixes of "123", including the root | |||
|
1047 | assert_eq!(idx.nt.masked_readonly_blocks(), 4); | |||
1021 |
|
1048 | |||
|
1049 | eprintln!("{:?}", idx.nt); | |||
1022 | idx.insert(5, "c0")?; |
|
1050 | idx.insert(5, "c0")?; | |
1023 | assert_eq!(idx.find_hex("cafe")?, Some(3)); |
|
1051 | assert_eq!(idx.find_hex("cafe")?, Some(3)); | |
1024 | assert_eq!(idx.find_hex("c0")?, Some(5)); |
|
1052 | assert_eq!(idx.find_hex("c0")?, Some(5)); | |
1025 | assert_eq!(idx.find_hex("c1")?, None); |
|
1053 | assert_eq!(idx.find_hex("c1")?, None); | |
1026 | assert_eq!(idx.find_hex("1234")?, Some(0)); |
|
1054 | assert_eq!(idx.find_hex("1234")?, Some(0)); | |
|
1055 | // inserting "c0" is just splitting the 'c' slot of the mutable root, | |||
|
1056 | // it doesn't mask anything | |||
|
1057 | assert_eq!(idx.nt.masked_readonly_blocks(), 4); | |||
1027 |
|
1058 | |||
1028 | Ok(()) |
|
1059 | Ok(()) | |
1029 | } |
|
1060 | } |
General Comments 0
You need to be logged in to leave comments.
Login now