immutable_chunkmap/
chunk.rs

1use alloc::{sync::Arc, vec::Vec};
2use arrayvec::ArrayVec;
3use core::{
4    borrow::Borrow,
5    cmp::{min, Ord, Ordering},
6    fmt::{self, Debug, Formatter},
7    iter, mem,
8    ops::Deref,
9    slice,
10};
11
12#[cfg(feature = "pool")]
13use core::{mem::ManuallyDrop, ptr};
14#[cfg(feature = "pool")]
15use poolshark::{
16    local::{insert_raw, take},
17    location_id, Discriminant, IsoPoolable, Poolable,
18};
19
20#[derive(PartialEq)]
21pub(crate) enum Loc {
22    InRight,
23    InLeft,
24    NotPresent(usize),
25    Here(usize),
26}
27
28/*
29elts is a sorted array of pairs, increasing the SIZE has several effects;
30
31-- decreases the height of the tree for a given number of elements,
32   decreasing the amount of indirection necessary to get to any given
33   key.
34
35-- decreases the number of objects allocated on the heap each time a
36   key is added or removed
37
38-- increases the size of each allocation
39
40-- icreases the overall amount of memory allocated for each change to
41   the tree
42*/
43pub const DEFAULT_SIZE: usize = 512;
44
45pub(crate) enum UpdateChunk<
46    Q: Ord,
47    K: Ord + Clone + Borrow<Q>,
48    V: Clone,
49    D,
50    const SIZE: usize,
51> {
52    UpdateLeft(Vec<(Q, D)>),
53    UpdateRight(Vec<(Q, D)>),
54    Updated {
55        elts: Chunk<K, V, SIZE>,
56        update_left: Vec<(Q, D)>,
57        update_right: Vec<(Q, D)>,
58        overflow_right: Vec<(K, V)>,
59    },
60    Removed {
61        not_done: Vec<(Q, D)>,
62        update_left: Vec<(Q, D)>,
63        update_right: Vec<(Q, D)>,
64    },
65}
66
67pub(crate) enum Update<Q: Ord, K: Ord + Clone + Borrow<Q>, V: Clone, D, const SIZE: usize>
68{
69    UpdateLeft(Q, D),
70    UpdateRight(Q, D),
71    Updated {
72        elts: Chunk<K, V, SIZE>,
73        overflow: Option<(K, V)>,
74        previous: Option<V>,
75    },
76}
77
78pub(crate) enum MutUpdate<Q: Ord, K: Ord + Clone + Borrow<Q>, V: Clone, D> {
79    UpdateLeft(Q, D),
80    UpdateRight(Q, D),
81    Updated {
82        overflow: Option<(K, V)>,
83        previous: Option<V>,
84    },
85}
86
87#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
88pub(crate) struct ChunkInner<K, V, const SIZE: usize> {
89    keys: ArrayVec<K, SIZE>,
90    vals: ArrayVec<V, SIZE>,
91}
92
93#[cfg(feature = "pool")]
94impl<K, V, const SIZE: usize> ChunkInner<K, V, SIZE> {
95    fn new() -> Self {
96        Self {
97            keys: ArrayVec::new(),
98            vals: ArrayVec::new(),
99        }
100    }
101
102    fn reset(&mut self) {
103        self.keys.clear();
104        self.vals.clear();
105    }
106}
107
108#[cfg(feature = "pool")]
109#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
110pub(crate) struct Chunk<K: Ord + Clone, V: Clone, const SIZE: usize>(
111    ManuallyDrop<Arc<ChunkInner<K, V, SIZE>>>,
112);
113
114#[cfg(feature = "pool")]
115impl<K: Ord + Clone, V: Clone, const SIZE: usize> Poolable for Chunk<K, V, SIZE> {
116    fn capacity(&self) -> usize {
117        1
118    }
119
120    fn empty() -> Self {
121        Self(ManuallyDrop::new(Arc::new(ChunkInner::new())))
122    }
123
124    fn really_dropped(&mut self) -> bool {
125        Arc::get_mut(&mut self.0).is_some()
126    }
127
128    fn reset(&mut self) {
129        Arc::get_mut(&mut self.0).unwrap().reset()
130    }
131}
132
133#[cfg(feature = "pool")]
134unsafe impl<K: Ord + Clone, V: Clone, const SIZE: usize> IsoPoolable
135    for Chunk<K, V, SIZE>
136{
137    const DISCRIMINANT: Option<Discriminant> =
138        Discriminant::new_p2_size::<K, V, SIZE>(location_id!());
139}
140
141#[cfg(feature = "pool")]
142impl<K: Ord + Clone, V: Clone, const SIZE: usize> Drop for Chunk<K, V, SIZE> {
143    fn drop(&mut self) {
144        match Arc::get_mut(&mut self.0) {
145            None => unsafe {
146                ManuallyDrop::drop(&mut self.0);
147            },
148            Some(inner) => {
149                inner.reset();
150                if let Some(mut t) = unsafe { insert_raw::<Self>(ptr::read(self)) } {
151                    unsafe { ManuallyDrop::drop(&mut t.0) };
152                    mem::forget(t); // don't call ourselves recursively
153                }
154            }
155        }
156    }
157}
158
159#[cfg(not(feature = "pool"))]
160#[derive(Clone, PartialEq, Eq, PartialOrd, Ord)]
161pub(crate) struct Chunk<K: Ord + Clone, V: Clone, const SIZE: usize>(
162    Arc<ChunkInner<K, V, SIZE>>,
163);
164
165impl<K: Ord + Clone, V: Clone, const SIZE: usize> Deref for Chunk<K, V, SIZE> {
166    type Target = ChunkInner<K, V, SIZE>;
167
168    fn deref(&self) -> &Self::Target {
169        &*self.0
170    }
171}
172
173impl<K: Ord + Clone, V: Clone, const SIZE: usize> Debug for Chunk<K, V, SIZE>
174where
175    K: Debug,
176    V: Debug,
177{
178    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
179        f.debug_map().entries(self.into_iter()).finish()
180    }
181}
182
183impl<K: Ord + Clone, V: Clone, const SIZE: usize> Chunk<K, V, SIZE>
184where
185    K: Ord + Clone,
186    V: Clone,
187{
188    pub(crate) fn singleton(k: K, v: V) -> Self {
189        let mut t = Self::empty();
190        let inner = Arc::get_mut(&mut t.0).unwrap();
191        inner.keys.push(k);
192        inner.vals.push(v);
193        t
194    }
195
196    #[cfg(feature = "pool")]
197    fn make_mut<'a>(&'a mut self) -> &'a mut ChunkInner<K, V, SIZE> {
198        match Arc::get_mut(&mut *self.0).map(|i| i as *mut _) {
199            Some(i) => unsafe { &mut *i },
200            None => {
201                let mut ni = Self::empty();
202                *Arc::get_mut(&mut *ni.0).unwrap() = (**self.0).clone();
203                *self = ni;
204                Arc::get_mut(&mut *self.0).unwrap()
205            }
206        }
207    }
208
209    #[cfg(not(feature = "pool"))]
210    fn make_mut<'a>(&'a mut self) -> &'a mut ChunkInner<K, V, SIZE> {
211        Arc::make_mut(&mut self.0)
212    }
213
214    #[cfg(feature = "pool")]
215    pub(crate) fn empty() -> Self {
216        take()
217    }
218
219    #[cfg(not(feature = "pool"))]
220    pub(crate) fn empty() -> Self {
221        Self(Arc::new(ChunkInner {
222            keys: ArrayVec::new(),
223            vals: ArrayVec::new(),
224        }))
225    }
226
227    pub(crate) fn create_with<Q, D, F>(chunk: Vec<(Q, D)>, f: &mut F) -> Self
228    where
229        Q: Ord,
230        K: Borrow<Q>,
231        F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>,
232    {
233        let mut t = Chunk::empty();
234        let inner = Arc::get_mut(&mut t.0).unwrap();
235        for (k, v) in chunk.into_iter().filter_map(|(q, d)| f(q, d, None)) {
236            inner.keys.push(k);
237            inner.vals.push(v);
238        }
239        t
240    }
241
242    pub(crate) fn get_local<Q: ?Sized + Ord>(&self, k: &Q) -> Option<usize>
243    where
244        K: Borrow<Q>,
245    {
246        match self.keys.binary_search_by_key(&k, |k| k.borrow()) {
247            Ok(i) => Some(i),
248            Err(_) => None,
249        }
250    }
251
252    pub(crate) fn get<Q: ?Sized + Ord>(&self, k: &Q) -> Loc
253    where
254        K: Borrow<Q>,
255    {
256        let len = self.len();
257        if len == 0 {
258            Loc::NotPresent(0)
259        } else {
260            let first = k.cmp(&self.keys[0].borrow());
261            let last = k.cmp(&self.keys[len - 1].borrow());
262            match (first, last) {
263                (Ordering::Equal, _) => Loc::Here(0),
264                (_, Ordering::Equal) => Loc::Here(len - 1),
265                (Ordering::Less, _) => Loc::InLeft,
266                (_, Ordering::Greater) => Loc::InRight,
267                (Ordering::Greater, Ordering::Less) => {
268                    match self.keys.binary_search_by_key(&k, |k| k.borrow()) {
269                        Result::Ok(i) => Loc::Here(i),
270                        Result::Err(i) => Loc::NotPresent(i),
271                    }
272                }
273            }
274        }
275    }
276
277    // invariant: chunk is sorted and deduped
278    pub(crate) fn update_chunk<Q, D, F>(
279        &self,
280        chunk: Vec<(Q, D)>,
281        leaf: bool,
282        f: &mut F,
283    ) -> UpdateChunk<Q, K, V, D, SIZE>
284    where
285        Q: Ord,
286        K: Borrow<Q>,
287        F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>,
288    {
289        assert!(chunk.len() <= SIZE && chunk.len() > 0 && self.len() > 0);
290        let full = !leaf || self.len() >= SIZE;
291        let in_left = self.get(&chunk[chunk.len() - 1].0) == Loc::InLeft;
292        let in_right = self.get(&chunk[0].0) == Loc::InRight;
293        if full && in_left {
294            UpdateChunk::UpdateLeft(chunk)
295        } else if full && in_right {
296            UpdateChunk::UpdateRight(chunk)
297        } else if leaf && (in_left || in_right) {
298            let iter = chunk.into_iter().filter_map(|(q, d)| f(q, d, None));
299            let mut overflow_right = Vec::new();
300            let mut elts = Chunk::empty();
301            let inner = Arc::get_mut(&mut elts.0).unwrap();
302            if in_right {
303                inner.clone_from(self);
304                for (k, v) in iter {
305                    if inner.keys.len() < SIZE {
306                        inner.keys.push(k);
307                        inner.vals.push(v);
308                    } else {
309                        overflow_right.push((k, v));
310                    }
311                }
312            } else {
313                for (k, v) in iter {
314                    if inner.keys.len() < SIZE {
315                        inner.keys.push(k);
316                        inner.vals.push(v);
317                    } else {
318                        overflow_right.push((k, v));
319                    }
320                }
321                for (k, v) in self.keys.iter().cloned().zip(self.vals.iter().cloned()) {
322                    if inner.keys.len() < SIZE {
323                        inner.keys.push(k);
324                        inner.vals.push(v);
325                    } else {
326                        overflow_right.push((k, v));
327                    }
328                }
329            }
330            UpdateChunk::Updated {
331                elts,
332                update_left: Vec::new(),
333                update_right: Vec::new(),
334                overflow_right,
335            }
336        } else {
337            #[inline(always)]
338            fn copy_up_to<K, V, const SIZE: usize>(
339                t: &Chunk<K, V, SIZE>,
340                elts: &mut ChunkInner<K, V, SIZE>,
341                overflow_right: &mut Vec<(K, V)>,
342                m: &mut usize,
343                i: usize,
344            ) where
345                K: Ord + Clone,
346                V: Clone,
347            {
348                let n = min(i.saturating_sub(*m), SIZE.saturating_sub(elts.keys.len()));
349                if n > 0 {
350                    elts.keys.extend(t.keys[*m..*m + n].iter().cloned());
351                    elts.vals.extend(t.vals[*m..*m + n].iter().cloned());
352                    *m += n;
353                }
354                if *m < i {
355                    overflow_right.extend(
356                        t.keys.as_slice()[*m..i]
357                            .iter()
358                            .cloned()
359                            .zip(t.vals.as_slice()[*m..i].iter().cloned()),
360                    );
361                    *m = i;
362                }
363            }
364            // invariant: don't cross the streams.
365            let mut not_done = Vec::new();
366            let mut update_left = Vec::new();
367            let mut update_right = Vec::new();
368            let mut overflow_right = Vec::new();
369            let mut m = 0;
370            let mut elts = Chunk::empty();
371            let inner = Arc::get_mut(&mut elts.0).unwrap();
372            let mut chunk = chunk.into_iter();
373            loop {
374                if m == self.len() && inner.keys.len() == 0 {
375                    not_done.extend(chunk);
376                    break;
377                }
378                match chunk.next() {
379                    None => {
380                        copy_up_to(self, inner, &mut overflow_right, &mut m, self.len());
381                        break;
382                    }
383                    Some((q, d)) => {
384                        match self.get(&q) {
385                            Loc::Here(i) => {
386                                copy_up_to(self, inner, &mut overflow_right, &mut m, i);
387                                let r = f(q, d, Some((&self.keys[i], &self.vals[i])));
388                                if let Some((k, v)) = r {
389                                    if inner.keys.len() < SIZE {
390                                        inner.keys.push(k);
391                                        inner.vals.push(v);
392                                    } else {
393                                        overflow_right.push((k, v))
394                                    }
395                                }
396                                // self[i] was replaced or deleted, skip it
397                                m += 1;
398                            }
399                            Loc::NotPresent(i) => {
400                                copy_up_to(self, inner, &mut overflow_right, &mut m, i);
401                                if let Some((k, v)) = f(q, d, None) {
402                                    if inner.keys.len() < SIZE {
403                                        inner.keys.push(k);
404                                        inner.vals.push(v);
405                                    } else {
406                                        overflow_right.push((k, v));
407                                    }
408                                }
409                            }
410                            Loc::InLeft => {
411                                if leaf && inner.keys.len() < SIZE {
412                                    if let Some((k, v)) = f(q, d, None) {
413                                        inner.keys.push(k);
414                                        inner.vals.push(v);
415                                    }
416                                } else {
417                                    update_left.push((q, d))
418                                }
419                            }
420                            Loc::InRight => {
421                                let len = self.len();
422                                copy_up_to(self, inner, &mut overflow_right, &mut m, len);
423                                if leaf && inner.keys.len() < SIZE {
424                                    let iter = iter::once((q, d))
425                                        .chain(chunk)
426                                        .filter_map(|(q, d)| f(q, d, None));
427                                    for (k, v) in iter {
428                                        if inner.keys.len() < SIZE {
429                                            inner.keys.push(k);
430                                            inner.vals.push(v);
431                                        } else {
432                                            overflow_right.push((k, v));
433                                        }
434                                    }
435                                } else {
436                                    update_right.push((q, d));
437                                    update_right.extend(chunk);
438                                }
439                                break;
440                            }
441                        }
442                    }
443                }
444            }
445            if elts.len() > 0 {
446                assert_eq!(not_done.len(), 0);
447                UpdateChunk::Updated {
448                    elts,
449                    update_left,
450                    update_right,
451                    overflow_right,
452                }
453            } else {
454                assert_eq!(overflow_right.len(), 0);
455                UpdateChunk::Removed {
456                    not_done,
457                    update_left,
458                    update_right,
459                }
460            }
461        }
462    }
463
464    pub(crate) fn update<Q, D, F>(
465        &self,
466        q: Q,
467        d: D,
468        leaf: bool,
469        f: &mut F,
470    ) -> Update<Q, K, V, D, SIZE>
471    where
472        Q: Ord,
473        K: Borrow<Q>,
474        F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>,
475    {
476        match self.get(&q) {
477            Loc::Here(i) => {
478                let mut elts = Chunk::empty();
479                let inner = Arc::get_mut(&mut elts.0).unwrap();
480                inner.keys.extend(self.keys[0..i].iter().cloned());
481                inner.vals.extend(self.vals[0..i].iter().cloned());
482                if let Some((k, v)) = f(q, d, Some((&self.keys[i], &self.vals[i]))) {
483                    inner.keys.push(k);
484                    inner.vals.push(v);
485                }
486                if i + 1 < self.len() {
487                    inner
488                        .keys
489                        .extend(self.keys[i + 1..self.len()].iter().cloned());
490                    inner
491                        .vals
492                        .extend(self.vals[i + 1..self.len()].iter().cloned());
493                }
494                Update::Updated {
495                    elts,
496                    overflow: None,
497                    previous: Some(self.vals[i].clone()),
498                }
499            }
500            Loc::NotPresent(i) => {
501                let mut elts = Chunk::empty();
502                let inner = Arc::get_mut(&mut elts.0).unwrap();
503                inner.keys.extend(self.keys[0..i].iter().cloned());
504                inner.vals.extend(self.vals[0..i].iter().cloned());
505                let overflow = match f(q, d, None) {
506                    None => None,
507                    Some((k, v)) => {
508                        if inner.keys.len() == SIZE {
509                            let (ok, ov) =
510                                (inner.keys.pop().unwrap(), inner.vals.pop().unwrap());
511                            inner.keys.push(k);
512                            inner.vals.push(v);
513                            Some((ok, ov))
514                        } else {
515                            inner.keys.push(k);
516                            inner.vals.push(v);
517                            let mut iter = self.keys[i..self.len()]
518                                .iter()
519                                .cloned()
520                                .zip(self.vals[i..self.len()].iter().cloned());
521                            loop {
522                                match iter.next() {
523                                    None => break None,
524                                    Some((k, v)) => {
525                                        if inner.keys.len() < SIZE {
526                                            inner.keys.push(k);
527                                            inner.vals.push(v);
528                                        } else {
529                                            break Some((k, v));
530                                        }
531                                    }
532                                }
533                            }
534                        }
535                    }
536                };
537                Update::Updated {
538                    elts,
539                    overflow,
540                    previous: None,
541                }
542            }
543            loc @ Loc::InLeft | loc @ Loc::InRight => {
544                if !leaf || self.len() == SIZE {
545                    match loc {
546                        Loc::InLeft => Update::UpdateLeft(q, d),
547                        Loc::InRight => Update::UpdateRight(q, d),
548                        Loc::Here(..) | Loc::NotPresent(..) => unreachable!(),
549                    }
550                } else {
551                    let mut elts = Chunk::empty();
552                    let inner = Arc::get_mut(&mut elts.0).unwrap();
553                    match loc {
554                        Loc::InLeft => {
555                            if let Some((k, v)) = f(q, d, None) {
556                                inner.keys.push(k);
557                                inner.vals.push(v);
558                            }
559                            inner.keys.extend(self.keys[0..self.len()].iter().cloned());
560                            inner.vals.extend(self.vals[0..self.len()].iter().cloned());
561                        }
562                        Loc::InRight => {
563                            inner.keys.extend(self.keys[0..self.len()].iter().cloned());
564                            inner.vals.extend(self.vals[0..self.len()].iter().cloned());
565                            if let Some((k, v)) = f(q, d, None) {
566                                inner.keys.push(k);
567                                inner.vals.push(v);
568                            }
569                        }
570                        _ => unreachable!("bug"),
571                    };
572                    Update::Updated {
573                        elts,
574                        overflow: None,
575                        previous: None,
576                    }
577                }
578            }
579        }
580    }
581
582    pub(crate) fn update_mut<Q, D, F>(
583        &mut self,
584        q: Q,
585        d: D,
586        leaf: bool,
587        f: &mut F,
588    ) -> MutUpdate<Q, K, V, D>
589    where
590        Q: Ord,
591        K: Borrow<Q>,
592        F: FnMut(Q, D, Option<(&K, &V)>) -> Option<(K, V)>,
593    {
594        match self.get(&q) {
595            Loc::Here(i) => match f(q, d, Some((&self.keys[i], &self.vals[i]))) {
596                Some((k, v)) => {
597                    let inner = self.make_mut();
598                    inner.keys[i] = k;
599                    MutUpdate::Updated {
600                        overflow: None,
601                        previous: Some(mem::replace(&mut inner.vals[i], v)),
602                    }
603                }
604                None => {
605                    let inner = self.make_mut();
606                    inner.keys.remove(i);
607                    MutUpdate::Updated {
608                        overflow: None,
609                        previous: Some(inner.vals.remove(i)),
610                    }
611                }
612            },
613            Loc::NotPresent(i) => match f(q, d, None) {
614                Some((k, v)) => {
615                    let inner = self.make_mut();
616                    let overflow = if inner.keys.len() == SIZE {
617                        let (ok, ov) =
618                            (inner.keys.pop().unwrap(), inner.vals.pop().unwrap());
619                        inner.keys.insert(i, k);
620                        inner.vals.insert(i, v);
621                        Some((ok, ov))
622                    } else {
623                        inner.keys.insert(i, k);
624                        inner.vals.insert(i, v);
625                        None
626                    };
627                    MutUpdate::Updated {
628                        overflow,
629                        previous: None,
630                    }
631                }
632                None => MutUpdate::Updated {
633                    overflow: None,
634                    previous: None,
635                },
636            },
637            loc @ Loc::InLeft | loc @ Loc::InRight => {
638                if !leaf || self.len() == SIZE {
639                    match loc {
640                        Loc::InLeft => MutUpdate::UpdateLeft(q, d),
641                        Loc::InRight => MutUpdate::UpdateRight(q, d),
642                        Loc::Here(..) | Loc::NotPresent(..) => unreachable!(),
643                    }
644                } else {
645                    let inner = self.make_mut();
646                    match loc {
647                        Loc::InLeft => {
648                            if let Some((k, v)) = f(q, d, None) {
649                                inner.keys.insert(0, k);
650                                inner.vals.insert(0, v);
651                            }
652                        }
653                        Loc::InRight => {
654                            if let Some((k, v)) = f(q, d, None) {
655                                inner.keys.push(k);
656                                inner.vals.push(v);
657                            }
658                        }
659                        _ => unreachable!("bug"),
660                    };
661                    MutUpdate::Updated {
662                        overflow: None,
663                        previous: None,
664                    }
665                }
666            }
667        }
668    }
669
670    pub(crate) fn intersect<F>(
671        c0: &Chunk<K, V, SIZE>,
672        c1: &Chunk<K, V, SIZE>,
673        r: &mut Vec<(K, V)>,
674        f: &mut F,
675    ) where
676        F: FnMut(&K, &V, &V) -> Option<V>,
677    {
678        if c0.len() > 0 && c1.len() > 0 {
679            let (c0, c1) = if c0.len() < c1.len() {
680                (c0, c1)
681            } else {
682                (c1, c0)
683            };
684            r.extend(c0.keys.iter().enumerate().filter_map(|(i, k)| {
685                match c1.keys.binary_search(&k) {
686                    Err(_) => None,
687                    Ok(j) => f(k, &c0.vals[i], &c1.vals[j]).map(|v| (k.clone(), v)),
688                }
689            }))
690        }
691    }
692
693    pub(crate) fn remove_elt_at(&self, i: usize) -> Self {
694        let mut elts = Chunk::empty();
695        let t = Arc::get_mut(&mut elts.0).unwrap();
696        if i >= self.keys.len() {
697            panic!("remove_elt_at: out of bounds")
698        } else if self.len() == 1 {
699            elts
700        } else if i == 0 {
701            t.keys.extend(self.keys[1..self.len()].iter().cloned());
702            t.vals.extend(self.vals[1..self.len()].iter().cloned());
703            elts
704        } else if i == self.keys.len() - 1 {
705            t.keys.extend(self.keys[0..self.len() - 1].iter().cloned());
706            t.vals.extend(self.vals[0..self.len() - 1].iter().cloned());
707            elts
708        } else {
709            t.keys.extend(self.keys[0..i].iter().cloned());
710            t.keys.extend(self.keys[i + 1..self.len()].iter().cloned());
711            t.vals.extend(self.vals[0..i].iter().cloned());
712            t.vals.extend(self.vals[i + 1..self.len()].iter().cloned());
713            elts
714        }
715    }
716
717    pub(crate) fn remove_elt_at_mut(&mut self, i: usize) -> (K, V) {
718        if i >= self.len() {
719            panic!("remove_elt_at_mut: out of bounds")
720        } else {
721            let inner = self.make_mut();
722            let k = inner.keys.remove(i);
723            let v = inner.vals.remove(i);
724            (k, v)
725        }
726    }
727
728    pub(crate) fn append<I: IntoIterator<Item = (K, V)>>(&self, other: I) -> Self {
729        let mut elts = self.clone();
730        let inner = elts.make_mut();
731        for (k, v) in other {
732            if inner.keys.len() < SIZE {
733                inner.keys.push(k);
734                inner.vals.push(v);
735            }
736        }
737        elts
738    }
739
740    pub(crate) fn min_max_key(&self) -> Option<(K, K)> {
741        if self.len() == 0 {
742            None
743        } else {
744            Some((self.keys[0].clone(), self.keys[self.len() - 1].clone()))
745        }
746    }
747
748    pub(crate) fn min_elt(&self) -> Option<(&K, &V)> {
749        if self.len() == 0 {
750            None
751        } else {
752            Some((&self.keys[0], &self.vals[0]))
753        }
754    }
755
756    pub(crate) fn max_elt(&self) -> Option<(&K, &V)> {
757        if self.len() == 0 {
758            None
759        } else {
760            let last = self.len() - 1;
761            Some((&self.keys[last], &self.vals[last]))
762        }
763    }
764
765    pub(crate) fn len(&self) -> usize {
766        self.keys.len()
767    }
768
769    pub(crate) fn key(&self, i: usize) -> &K {
770        &self.keys[i]
771    }
772
773    pub(crate) fn val(&self, i: usize) -> &V {
774        &self.vals[i]
775    }
776
777    pub(crate) fn val_mut(&mut self, i: usize) -> &mut V {
778        &mut self.make_mut().vals[i]
779    }
780
781    pub(crate) fn kv(&self, i: usize) -> (&K, &V) {
782        (&self.keys[i], &self.vals[i])
783    }
784
785    pub(crate) fn to_vec(&self) -> Vec<(K, V)> {
786        self.into_iter()
787            .map(|(k, v)| (k.clone(), v.clone()))
788            .collect()
789    }
790}
791
792impl<K: Ord + Clone, V: Clone, const SIZE: usize> IntoIterator for Chunk<K, V, SIZE> {
793    type Item = (K, V);
794    type IntoIter = iter::Zip<arrayvec::IntoIter<K, SIZE>, arrayvec::IntoIter<V, SIZE>>;
795    fn into_iter(mut self) -> Self::IntoIter {
796        let inner = mem::replace(
797            self.make_mut(),
798            ChunkInner {
799                keys: ArrayVec::new(),
800                vals: ArrayVec::new(),
801            },
802        );
803        inner.keys.into_iter().zip(inner.vals.into_iter())
804    }
805}
806
807impl<'a, K: Ord + Clone, V: Clone, const SIZE: usize> IntoIterator
808    for &'a Chunk<K, V, SIZE>
809{
810    type Item = (&'a K, &'a V);
811    type IntoIter = iter::Zip<slice::Iter<'a, K>, slice::Iter<'a, V>>;
812    fn into_iter(self) -> Self::IntoIter {
813        (&self.keys).into_iter().zip(&self.vals)
814    }
815}
816
817impl<'a, K: Ord + Clone, V: Clone, const SIZE: usize> IntoIterator
818    for &'a mut Chunk<K, V, SIZE>
819{
820    type Item = (&'a K, &'a mut V);
821    type IntoIter = iter::Zip<slice::Iter<'a, K>, slice::IterMut<'a, V>>;
822    fn into_iter(self) -> Self::IntoIter {
823        let inner = self.make_mut();
824        (&inner.keys).into_iter().zip(&mut inner.vals)
825    }
826}