node.rs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /// A block list node.
  2. ///
  3. /// A node consists of three components:
  4. ///
  5. /// 1. The inner value that the node holds.
  6. /// 2. A pointer to the next node.
  7. /// 3. A stack of so called "shortcuts", which contains data about jumping over/searching for
  8. /// nodes.
  9. struct Node {
  10. /// The inner block.
  11. ///
  12. /// This should never be empty (zero-sized).
  13. block: Block,
  14. /// The node that follows this node.
  15. ///
  16. /// This cannot be adjacent (tangent) to `self.block`. It is important to maintain the blocks
  17. /// as long as possible, and hence merge if that is the case.
  18. ///
  19. /// `None` indicates that the node is the last node in the list.
  20. next: Option<Jar<Node>>,
  21. /// Shortcuts/jumps of the current node.
  22. ///
  23. /// This is a stack of linked list nodes, such that any entry has a list which is a superset of
  24. /// the latter. The lowest layer is a subset of the block list itself.
  25. ///
  26. /// ...
  27. /// 2 # ---------------------> [6] ---------------------> [9] -------------> NIL
  28. /// 1 # ---------------------> [6] ---> [7] ------------> [9] -------------> NIL
  29. /// 0 # ------------> [5] ---> [6] ---> [7] ------------> [9] ---> [10] ---> NIL
  30. /// bottom # ---> [1] ---> [5] ---> [6] ---> [7] ---> [8] ---> [9] ---> [10] ---> NIL
  31. ///
  32. /// As a result the lowest entry is the most dense.
  33. ///
  34. /// If we assume our node is `[6]`, the stack would contain shotcuts to 7, 7, and 8, in that
  35. /// order. The rest would simply be null pointers with fat value 0.
  36. ///
  37. /// # Height
  38. ///
  39. /// The index of the highest null shortcut (or, if none, the length of the array) is called the
  40. /// height of the node.
  41. shortcuts: lv::Array<Shortcut>,
  42. }
  43. impl Node {
  44. /// Insert a new node after this node.
  45. fn insert(&mut self, new_node: Jar<Node>) {
  46. // TODO: Eliminate this (critical) memcpy.
  47. take::replace_with(self, |node| {
  48. new_node.next = Some(node);
  49. new_node
  50. });
  51. }
  52. // TODO: Implement `IntoIterator`.
  53. fn iter(&mut self) -> impl Iterator<Item = &Node> {
  54. PoolIter {
  55. node: Some(self),
  56. }
  57. }
  58. /// Create an iterator following the `lv`'th shortcut.
  59. fn follow_shortcut(&self, lv: shotcut::Level) -> impl Iterator<Item = Shortcut> {
  60. ShortcutIter {
  61. lv: lv,
  62. node: Some(self),
  63. }
  64. }
  65. /// An iterator over the shortcuts of this node.
  66. ///
  67. /// It starts with the lowest (densest) layer's shortcut and progress upwards.
  68. fn shortcuts(&self) -> impl Iterator<Item = Shortcut> {
  69. self.shortcuts.iter().take_while(|x| !x.is_null())
  70. }
  71. /// Calculate the fat value at some level based on the level below and the inner block's size.
  72. ///
  73. /// This will simply traverse the layer below (given in the form of an iterator) and find the
  74. /// maximal fat value. The result is guaranteed to be equal to or greater than
  75. /// `self.block.size()`.
  76. fn calculate_fat_value<I>(&self, lv: lv::Level, below: I) -> block::Size
  77. where I: Iterator<Item = &Node> {
  78. // We start at the block's size.
  79. let mut new_fat = 0;
  80. // The current skip at `lv`.
  81. let shortcut = &self.shortcuts[lv];
  82. // Avoid multiple checking branches for the sake of performance.
  83. let next_node = shortcut.next.get().unwrap();
  84. // Follow the shortcuts until we reach `new_node`.
  85. // TODO: Unroll the first iteration of the loop below to avoid the unneccesary
  86. // branch in the first iteration's call of `cmp::max`.
  87. for i in below {
  88. new_fat = cmp::max(i.fat, new_fat);
  89. // Check if the next node isn't reached yet.
  90. if i == next_node {
  91. break;
  92. }
  93. // We short-circuit in case we reached the old fat value, since the nodes
  94. // are bounded by this size and thus no bigger nodes are to be found.
  95. if new_fat == shortcut.fat {
  96. break;
  97. }
  98. // A note on code style: While it would be more idiomatic to make the above two
  99. // conditionals above into a `take_while` iterator. Unfortunately, this
  100. // introduces two (!) branches. Iterator adapters are not as zero-cost as
  101. // everybody claims.
  102. }
  103. new_fat
  104. }
  105. /// Calculate the fat value of a non bottom layer.
  106. pub fn calculate_fat_value_non_bottom(&self, lv: lv::NonBottomLevel) -> block::Size {
  107. // Since `lv != 0` decrementing will not underflow.
  108. self.calculate_fat_value(lv, self.shortcuts[lv.below()].follow_shortcut(lv.below()))
  109. }
  110. /// Calculate the fat value of the lowest level.
  111. pub fn calculate_fat_value_bottom(&self) -> block::Size {
  112. // We base the new fat value of the lowest layer on the block list.
  113. self.calculate_fat_value(lv::Level::min(), self.iter());
  114. }
  115. /// Check that this structure satisfy its invariants.
  116. ///
  117. /// This is NOP in release mode (`debug_assertions` disabled).
  118. #[inline]
  119. fn check(&self) {
  120. if cfg!(debug_assertions) {
  121. // Check against empty blocks.
  122. assert!(!self.block.is_empty(), "Node's block {:?} is empty (zero sized)", self.block);
  123. if let Some(next) = self.next {
  124. // First, make sure that our node is sorted with respect to the next node.
  125. assert!(next > self.block, "Node holding block {:?} is not sorted wrt. the next \
  126. block {:?}", self.block, next);
  127. // The nodes may never be adjacent. If they are, a merge have been missed.
  128. assert!(!self.block.left_to(next), "Node's block {:?} adjacent to the next node's \
  129. block {:?}", self.block, next);
  130. }
  131. // WHO'S A GOOD BOY???
  132. // .--~~,__
  133. // :-....,-------`~~'._.'
  134. // `-,,, ,_ ;'~U'
  135. // _,-' ,'`-__; '--.
  136. // (_/'~~ ''''(;
  137. // FIXME: The short-circuit in `calculate_fat_value` makes the check incomplete, if a
  138. // larger element follows.
  139. // Check the fat value of the bottom level.
  140. assert!(self.shortcuts[0].fat == self.calculate_fat_value_bottom(), "The bottom layer's \
  141. fat value does not match the calculated fat value.");
  142. // Check the fat values of the non bottom level.
  143. for lv in lv::Iter::non_bottom() {
  144. assert!(self.shortcuts[lv.into()].fat == self.calculate_fat_value_non_bottom(lv), "The \
  145. bottom layer's fat value does not match the calculated fat value.");
  146. }
  147. // Check that the shortcut refers to a node with appropriate (equal to or greater)
  148. // height.
  149. // FIXME: Fold this loop to the one above.
  150. for lv in lv::Iter::all() {
  151. assert!(!self.shortcuts[lv.into()].next.shortcuts[lv.into()].is_null(), "Shortcut \
  152. points to a node with a lower height. Is this a dangling pointer?");
  153. }
  154. }
  155. }
  156. }
  157. struct PoolIter<'a> {
  158. node: Option<&'a mut Node>,
  159. }
  160. impl<'a> Iterator for PoolIter<'a> {
  161. type Item = &'a mut Node;
  162. fn next(&mut self) -> &'a mut Node {
  163. // Replace `self.node` by the next shortcut, and return the old value.
  164. mem::replace(&mut self.node, self.node.and_then(|x| &mut x.next))
  165. }
  166. }