1use crate::{
2 generic::{
3 map::M,
4 node::{Balance, Item, Offset, WouldUnderflow},
5 },
6 utils::binary_search_min,
7};
8use smallvec::SmallVec;
9use std::borrow::Borrow;
10
11#[derive(Clone)]
12pub struct Leaf<K, V> {
13 parent: usize,
14 items: SmallVec<[Item<K, V>; M + 1]>,
15}
16
17impl<K, V> Leaf<K, V> {
18 #[inline]
19 pub fn new(parent: Option<usize>, item: Item<K, V>) -> Leaf<K, V> {
20 let mut items = SmallVec::new();
21 items.push(item);
22
23 Leaf {
24 parent: parent.unwrap_or(std::usize::MAX),
25 items,
26 }
27 }
28
29 #[inline]
30 pub fn parent(&self) -> Option<usize> {
31 if self.parent == std::usize::MAX {
32 None
33 } else {
34 Some(self.parent)
35 }
36 }
37
38 #[inline]
39 pub fn set_parent(&mut self, p: Option<usize>) {
40 self.parent = p.unwrap_or(std::usize::MAX);
41 }
42
43 #[inline]
44 pub fn item_count(&self) -> usize {
45 self.items.len()
46 }
47
48 #[inline]
49 pub fn items(&self) -> &[Item<K, V>] {
50 self.items.as_ref()
51 }
52
53 #[inline]
54 pub fn iter(&self) -> std::slice::Iter<Item<K, V>> {
55 self.items.as_ref().iter()
56 }
57
58 #[inline]
59 pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V>
60 where
61 K: Borrow<Q>,
62 Q: Ord,
63 {
64 match binary_search_min(&self.items, key) {
65 Some(i) => {
66 let item = &self.items[i];
67 if item.key().borrow() == key {
68 Some(item.value())
69 } else {
70 None
71 }
72 }
73 _ => None,
74 }
75 }
76
77 #[inline]
78 pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V>
79 where
80 K: Borrow<Q>,
81 Q: Ord,
82 {
83 match binary_search_min(&self.items, key) {
84 Some(i) => {
85 let item = &mut self.items[i];
86 if item.key().borrow() == key {
87 Some(item.value_mut())
88 } else {
89 None
90 }
91 }
92 _ => None,
93 }
94 }
95
96 #[inline]
98 pub fn offset_of<Q: ?Sized>(&self, key: &Q) -> Result<Offset, Offset>
99 where
100 K: Borrow<Q>,
101 Q: Ord,
102 {
103 match binary_search_min(&self.items, key) {
104 Some(i) => {
105 if self.items[i].key().borrow() == key {
106 Ok(i.into())
107 } else {
108 Err((i + 1).into())
109 }
110 }
111 None => Err(0.into()),
112 }
113 }
114
115 #[inline]
116 pub fn item(&self, offset: Offset) -> Option<&Item<K, V>> {
117 match offset.value() {
118 Some(offset) => self.items.get(offset),
119 None => None,
120 }
121 }
122
123 #[inline]
124 pub fn item_mut(&mut self, offset: Offset) -> Option<&mut Item<K, V>> {
125 match offset.value() {
126 Some(offset) => self.items.get_mut(offset),
127 None => None,
128 }
129 }
130
131 #[inline]
132 pub fn insert_by_key(&mut self, key: K, mut value: V) -> (Offset, Option<V>)
133 where
134 K: Ord,
135 {
136 match binary_search_min(&self.items, &key) {
137 Some(i) => {
138 if self.items[i].key() == &key {
139 std::mem::swap(&mut value, self.items[i].value_mut());
140 (i.into(), Some(value))
141 } else {
142 self.items.insert(i + 1, Item::new(key, value));
143 ((i + 1).into(), None)
144 }
145 }
146 None => {
147 self.items.insert(0, Item::new(key, value));
148 (0.into(), None)
149 }
150 }
151 }
152
153 #[inline]
154 pub fn split(&mut self) -> (usize, Item<K, V>, Leaf<K, V>) {
155 assert!(self.is_overflowing());
156
157 let median_i = (self.items.len() - 1) / 2;
158
159 let right_items = self.items.drain(median_i + 1..).collect();
160 let median = self.items.pop().unwrap();
161
162 let right_leaf = Leaf {
163 parent: self.parent,
164 items: right_items,
165 };
166
167 assert!(!self.is_underflowing());
168 assert!(!right_leaf.is_underflowing());
169
170 (self.items.len(), median, right_leaf)
171 }
172
173 #[inline]
174 pub fn append(&mut self, separator: Item<K, V>, mut other: Leaf<K, V>) -> Offset {
175 let offset = self.items.len();
176 self.items.push(separator);
177 self.items.append(&mut other.items);
178 offset.into()
179 }
180
181 #[inline]
182 pub fn push_left(&mut self, item: Item<K, V>) {
183 self.items.insert(0, item)
184 }
185
186 #[inline]
187 pub fn pop_left(&mut self) -> Result<Item<K, V>, WouldUnderflow> {
188 if self.item_count() < M / 2 {
189 Err(WouldUnderflow)
190 } else {
191 Ok(self.items.remove(0))
192 }
193 }
194
195 #[inline]
196 pub fn push_right(&mut self, item: Item<K, V>) -> Offset {
197 let offset = self.items.len();
198 self.items.push(item);
199 offset.into()
200 }
201
202 #[inline]
203 pub fn pop_right(&mut self) -> Result<(Offset, Item<K, V>), WouldUnderflow> {
204 if self.item_count() < M / 2 {
205 Err(WouldUnderflow)
206 } else {
207 let offset = self.items.len();
208 let item = self.items.pop().unwrap();
209 Ok((offset.into(), item))
210 }
211 }
212
213 #[inline]
214 pub fn balance(&self) -> Balance {
215 if self.is_overflowing() {
216 Balance::Overflow
217 } else if self.is_underflowing() {
218 Balance::Underflow(self.items.is_empty())
219 } else {
220 Balance::Balanced
221 }
222 }
223
224 #[inline]
225 pub fn is_overflowing(&self) -> bool {
226 self.item_count() > M
227 }
228
229 #[inline]
230 pub fn is_underflowing(&self) -> bool {
231 self.item_count() < M / 2 - 1
232 }
233
234 #[inline]
236 pub fn insert(&mut self, offset: Offset, item: Item<K, V>) {
237 match offset.value() {
238 Some(offset) => self.items.insert(offset, item),
239 None => panic!("Offset out of bounds"),
240 }
241 }
242
243 #[inline]
246 pub fn remove(&mut self, offset: Offset) -> Item<K, V> {
247 match offset.value() {
248 Some(offset) => self.items.remove(offset),
249 None => panic!("Offset out of bounds"),
250 }
251 }
252
253 #[inline]
254 pub fn remove_last(&mut self) -> Item<K, V> {
255 self.items.pop().unwrap()
256 }
257
258 #[cfg(feature = "dot")]
262 #[inline]
263 pub fn dot_write_label<W: std::io::Write>(&self, f: &mut W) -> std::io::Result<()>
264 where
265 K: std::fmt::Display,
266 V: std::fmt::Display,
267 {
268 for item in &self.items {
269 write!(f, "{{{}|{}}}|", item.key(), item.value())?;
270 }
271
272 Ok(())
273 }
274
275 #[cfg(debug_assertions)]
276 pub fn validate(&self, parent: Option<usize>, min: Option<&K>, max: Option<&K>)
277 where
278 K: Ord,
279 {
280 if self.parent() != parent {
281 panic!("wrong parent")
282 }
283
284 if min.is_some() || max.is_some() {
285 match self.balance() {
287 Balance::Overflow => panic!("leaf is overflowing"),
288 Balance::Underflow(_) => panic!("leaf is underflowing"),
289 _ => (),
290 }
291 }
292
293 if !self.items.windows(2).all(|w| w[0] < w[1]) {
294 panic!("leaf items are not sorted")
295 }
296
297 if let Some(min) = min {
298 if let Some(item) = self.items.first() {
299 if min >= item.key() {
300 panic!("leaf item key is greater than right separator")
301 }
302 }
303 }
304
305 if let Some(max) = max {
306 if let Some(item) = self.items.last() {
307 if max <= item.key() {
308 panic!("leaf item key is less than left separator")
309 }
310 }
311 }
312 }
313}