shortcut.rs 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. use block;
  2. /// A shortcut (a pointer to a later node and the size of the biggest block it skips).
  3. ///
  4. /// A shortcut stores two values: a pointer to the node it skips to, and the size of the "fat
  5. /// node(s)".
  6. ///
  7. /// # Span
  8. ///
  9. /// If a given node starts at $$a$$ and has a shortcut skipping to node $$b$$, then the shortcut's
  10. /// span is $$(a, b]$$. If it has no node to skip to (i.e. it is `None`), the shortcut spans from
  11. /// $$a$$ (exclusive) to the end of the list (inclusive).
  12. ///
  13. /// In other words, the node which holds the shortcut is not included in the span, but the node it
  14. /// skips to is included.
  15. ///
  16. /// # Fat nodes and fat values
  17. ///
  18. /// If a block $$c \in S$$ with $$S$$ being the span of some shortcut satisfy $c \geq d$$ for any
  19. /// $$d \in S$$, this node is said to be a _fat node_.
  20. ///
  21. /// In less formal terms, we can considered a fat node is (one of) the nodes with the biggest block
  22. /// in the span of the shortcut.
  23. ///
  24. /// The size of the fat nodes is called the _fat value_ of the shortcut.
  25. ///
  26. /// # Children
  27. ///
  28. /// Because we can view the shortcuts as a tree satisfying the heap property wrt. the fat value, we
  29. /// refer to shortcuts which are contained in another shortcut's span as children of said shortcut.
  30. #[derive(Default)]
  31. struct Shortcut {
  32. /// The node it skips to (if any).
  33. next: Option<Pointer<Node>>,
  34. /// The fat value of this shortcut.
  35. ///
  36. /// This is the size of the biggest block the shortcut spans.
  37. fat: block::Size,
  38. }
  39. impl Shortcut {
  40. #[inline]
  41. fn is_null(&self) -> bool {
  42. self.fat == 0
  43. }
  44. /// Increase the fat value in case the new node is bigger than the current fat node.
  45. ///
  46. /// When inserting it is important for us to maintain the invariants. In this case, keeping
  47. /// track of the size of the biggest node skipped. When a new node is inserted, this value
  48. /// should naturally reflect that. If the new node's size is in fact greater than the fat
  49. /// value, the fat value will be updated.
  50. ///
  51. /// However, if a node is removed, this function is not the appropriate one to update the fat
  52. /// value, since such an operation might decrease the fat value, rather than increase it.
  53. ///
  54. /// # Short-circuiting
  55. ///
  56. /// The returned value indicates if the caller should continue propagating new fat value up.
  57. /// This can be either because the updated fat value is equal to old fat value, or that the
  58. /// shortcut was null (and thus all higher shortcuts are too).
  59. ///
  60. /// The former is based on the observation that updating the fat value is similar to heap insertion.
  61. ///
  62. /// Consider insertion a block of size 4:
  63. /// [6] -6-------------------> ...
  64. /// [6] -6-------------------> ...
  65. /// [6] -6--------> [2] -2---> ...
  66. /// [6] -6--------> [4] -4---> ...
  67. /// Clearly, all the unchanged fat values of the two highest levels are correct, but the third
  68. /// level's value following [2] is not. So we can shortcircuit when we get to the second last
  69. /// level, due to the fact that the tree of the shortcut's fat values satisfy the heap
  70. /// property:
  71. ///
  72. /// 6
  73. /// |
  74. /// 6
  75. /// / \
  76. /// 6 |
  77. /// 4
  78. /// |
  79. /// 2
  80. ///
  81. /// Let $$A$$ be a node with set of children $$C$$, then $$A = \max(C)$$. As such, if I start
  82. /// in the bottom and iterate upwards, as soon as the value stays unchanged, the rest of the
  83. /// values won't change either.
  84. #[inline]
  85. fn increase_fat(&mut self, new_size: block::Size) -> bool {
  86. if self.fat < new_size && !self.is_null() {
  87. // The fat value is smaller than the new size and thus an update is required.
  88. self.fat = new_size;
  89. true
  90. } else {
  91. // Since the old fat value is either not smaller than or empty, we can safely
  92. // shortcircuits (see the notes layed out in the documentation comment).
  93. false
  94. }
  95. }
  96. }
  97. struct ShortcutIter<'a> {
  98. lv: Level,
  99. shortcut: Option<&'a Shortcut>,
  100. }
  101. impl<'a> ShortcutIter<'a> {
  102. /// Decrement the shortcut level of this iterator and return the old level.
  103. ///
  104. /// This will make the iterator skip approximately half of the elements of the previous state
  105. /// of the iterator.
  106. #[inline]
  107. fn decrement_level(&mut self) -> Level {
  108. let lv = self.lv;
  109. self.lv -= Level(1);
  110. lv
  111. }
  112. /// Unwrap the inner node (of the shortcut that the iterator is currently on).
  113. ///
  114. /// # Panics
  115. ///
  116. /// This will panic if the iterator is over (i.e. no node is left)
  117. #[inline]
  118. fn unwrap_node(self) -> &Node {
  119. self.shortcut.unwrap().node
  120. }
  121. }
  122. impl<'a> Iterator for ShortcutIter<'a> {
  123. type Item = &'a Shortcut;
  124. fn next(&mut self) -> &'a mut Shortcut {
  125. // Replace `self.shortcut` by the next shortcut, and return the old value.
  126. mem::replace(&mut self.shortcut, self.shortcut.map(|x| x.shortcut[self.lv].get()))
  127. }
  128. }