Skip to main content

columnar/
lookback.rs

1//! Containers that can store either values, or offsets to prior values.
2//!
3//! This has the potential to be more efficient than a list of `T` when many values repeat in
4//! close proximity. Values must be equatable, and the degree of lookback can be configured.
5use alloc::{vec::Vec, string::String};
6
7use crate::{Options, Results, Push, Index, Len, Clear, Borrow, Container, IndexAs};
8
9/// A container that encodes repeated values with a `None` variant, at the cost of extra bits for every record.
10#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
11#[derive(Copy, Clone, Debug, Default, PartialEq)]
12pub struct Repeats<TC, CC=Vec<u64>, VC=Vec<u64>, WC=[u64; 2]> {
13    /// Some(x) encodes a value, and None indicates the prior `x` value.
14    pub inner: Options<TC, CC, VC, WC>,
15}
16
17impl<T: PartialEq, TC: Push<T> + Len> Push<T> for Repeats<TC>
18where
19    for<'a> &'a TC: Index,
20    for<'a> <&'a TC as Index>::Ref : PartialEq<T>,
21{
22    #[inline]
23    fn push(&mut self, item: T) {
24        // Look at the last `somes` value for a potential match.
25        let insert: Option<T> = if (&self.inner.somes).last().map(|x| x.eq(&item)) == Some(true) {
26            None
27        } else {
28            Some(item)
29        };
30        self.inner.push(insert);
31    }
32}
33
34impl<TC, CC, VC: Len, WC: IndexAs<u64>> Len for Repeats<TC, CC, VC, WC> {
35    #[inline(always)] fn len(&self) -> usize { self.inner.len() }
36}
37
38impl<TC: Index, CC: IndexAs<u64> + Len, VC: IndexAs<u64> + Len, WC: IndexAs<u64>> Index for Repeats<TC, CC, VC, WC> {
39    type Ref = TC::Ref;
40    #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
41        match self.inner.get(index) {
42            Some(item) => item,
43            None => {
44                let pos = self.inner.indexes.rank(index) - 1;
45                self.inner.somes.get(pos)
46            },
47        }
48    }
49}
50
51impl<'a, TC> Index for &'a Repeats<TC>
52where
53    &'a TC: Index,
54{
55    type Ref = <&'a TC as Index>::Ref;
56    #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
57        match (&self.inner).get(index) {
58            Some(item) => item,
59            None => {
60                let pos = self.inner.indexes.rank(index) - 1;
61                (&self.inner.somes).get(pos)
62            },
63        }
64    }
65}
66
67impl<TC: Borrow> Borrow for Repeats<TC> {
68    type Ref<'a> = TC::Ref<'a> where TC: 'a;
69    type Borrowed<'a> = Repeats<TC::Borrowed<'a>, &'a [u64], &'a [u64], &'a [u64]> where TC: 'a;
70    #[inline(always)]
71    fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
72        Repeats { inner: self.inner.borrow() }
73    }
74    #[inline(always)]
75    fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where TC: 'a {
76        Repeats { inner: Options::<TC>::reborrow(thing.inner) }
77    }
78    #[inline(always)]
79    fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a {
80        TC::reborrow_ref(thing)
81    }
82}
83
84impl<TC: Container> Container for Repeats<TC>
85where
86    for<'a> &'a TC: Index,
87    for<'a> TC::Ref<'a>: PartialEq,
88    for<'a, 'b> <&'a TC as Index>::Ref: PartialEq<TC::Ref<'b>>,
89{
90    fn extend_from_self(&mut self, other: Self::Borrowed<'_>, range: core::ops::Range<usize>) {
91        if !range.is_empty() {
92            // Push the first element, resolving any `None` to its actual value.
93            self.push(other.get(range.start));
94            // The remaining elements can be bulk-copied from the inner `Options`,
95            // as any `None` now has a preceding `Some` to reference.
96            if range.start + 1 < range.end {
97                self.inner.extend_from_self(other.inner, range.start + 1 .. range.end);
98            }
99        }
100    }
101
102    fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
103        self.inner.somes.reserve_for(selves.map(|x| x.inner.somes));
104    }
105}
106
107impl<TC: Clear> Clear for Repeats<TC> {
108    fn clear(&mut self) {
109        self.inner.clear();
110    }
111}
112
113impl<'a, TC: crate::AsBytes<'a>, CC: crate::AsBytes<'a>, VC: crate::AsBytes<'a>> crate::AsBytes<'a> for Repeats<TC, CC, VC, &'a [u64]> {
114    const SLICE_COUNT: usize = <Options<TC, CC, VC, &'a [u64]> as crate::AsBytes<'a>>::SLICE_COUNT;
115    #[inline]
116    fn get_byte_slice(&self, index: usize) -> (u64, &'a [u8]) {
117        self.inner.get_byte_slice(index)
118    }
119}
120
121impl<'a, TC: crate::FromBytes<'a>, CC: crate::FromBytes<'a>, VC: crate::FromBytes<'a>> crate::FromBytes<'a> for Repeats<TC, CC, VC, &'a [u64]> {
122    const SLICE_COUNT: usize = <Options<TC, CC, VC, &'a [u64]>>::SLICE_COUNT;
123    #[inline(always)]
124    fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
125        Self { inner: crate::FromBytes::from_bytes(bytes) }
126    }
127    #[inline(always)]
128    fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
129        Self { inner: crate::FromBytes::from_store(store, offset) }
130    }
131    #[inline(always)]
132    fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
133        <Options<TC, CC, VC, &'a [u64]>>::element_sizes(sizes)
134    }
135}
136
137#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
138#[derive(Copy, Clone, Debug, Default, PartialEq)]
139pub struct Lookbacks<TC, VC = Vec<u8>, CC=Vec<u64>, RC=Vec<u64>, WC=[u64; 2], const N: u8 = 255> {
140    /// Ok(x) encodes a value, and Err(y) indicates a value `y` back.
141    pub inner: Results<TC, VC, CC, RC, WC>,
142}
143
144impl<T: PartialEq, TC: Push<T> + Len, VC: Push<u8>, const N: u8> Push<T> for Lookbacks<TC, VC, Vec<u64>, Vec<u64>, [u64; 2], N>
145where
146    for<'a> &'a TC: Index,
147    for<'a> <&'a TC as Index>::Ref : PartialEq<T>,
148{
149    #[inline]
150    fn push(&mut self, item: T) {
151        // Look backwards through (0 .. N) to look for a matching value.
152        let oks_len = self.inner.oks.len();
153        let find = (0u8 .. N).take(self.inner.oks.len()).find(|i| (&self.inner.oks).get(oks_len - (*i as usize) - 1) == item);
154        let insert: Result<T, u8> = if let Some(back) = find { Err(back) } else { Ok(item) };
155        self.inner.push(insert);
156    }
157}
158
159impl<TC, VC, CC, RC: Len, WC: IndexAs<u64>, const N: u8> Len for Lookbacks<TC, VC, CC, RC, WC, N> {
160    #[inline(always)] fn len(&self) -> usize { self.inner.len() }
161}
162
163impl<TC: Index, VC: IndexAs<u8>, CC: IndexAs<u64> + Len, RC: IndexAs<u64> + Len, WC: IndexAs<u64>, const N: u8> Index for Lookbacks<TC, VC, CC, RC, WC, N> {
164    type Ref = TC::Ref;
165    #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
166        let rank = self.inner.indexes.rank(index);
167        if self.inner.indexes.get(index) {
168            self.inner.oks.get(rank)
169        } else {
170            let back: u8 = self.inner.errs.index_as(index - rank);
171            self.inner.oks.get(rank - 1 - (back as usize))
172        }
173    }
174}
175
176impl<'a, TC, const N: u8> Index for &'a Lookbacks<TC, Vec<u8>, Vec<u64>, Vec<u64>, [u64; 2], N>
177where
178    &'a TC: Index,
179{
180    type Ref = <&'a TC as Index>::Ref;
181    #[inline(always)] fn get(&self, index: usize) -> Self::Ref {
182        let rank = self.inner.indexes.rank(index);
183        if self.inner.indexes.get(index) {
184            (&self.inner.oks).get(rank)
185        } else {
186            let back: u8 = self.inner.errs.index_as(index - rank);
187            (&self.inner.oks).get(rank - 1 - (back as usize))
188        }
189    }
190}
191
192impl<TC: Borrow, const N: u8> Borrow for Lookbacks<TC, Vec<u8>, Vec<u64>, Vec<u64>, [u64; 2], N> {
193    type Ref<'a> = TC::Ref<'a> where TC: 'a;
194    type Borrowed<'a> = Lookbacks<TC::Borrowed<'a>, &'a [u8], &'a [u64], &'a [u64], &'a [u64], N> where TC: 'a;
195    #[inline(always)]
196    fn borrow<'a>(&'a self) -> Self::Borrowed<'a> {
197        Lookbacks { inner: self.inner.borrow() }
198    }
199    #[inline(always)]
200    fn reborrow<'b, 'a: 'b>(thing: Self::Borrowed<'a>) -> Self::Borrowed<'b> where TC: 'a {
201        Lookbacks { inner: Results::<TC, Vec<u8>>::reborrow(thing.inner) }
202    }
203    #[inline(always)]
204    fn reborrow_ref<'b, 'a: 'b>(thing: Self::Ref<'a>) -> Self::Ref<'b> where Self: 'a {
205        TC::reborrow_ref(thing)
206    }
207}
208
209impl<TC: Container, const N: u8> Container for Lookbacks<TC, Vec<u8>, Vec<u64>, Vec<u64>, [u64; 2], N>
210where
211    for<'a> &'a TC: Index,
212    for<'a> TC::Ref<'a>: PartialEq,
213    for<'a, 'b> <&'a TC as Index>::Ref: PartialEq<TC::Ref<'b>>,
214{
215    // Lookback offsets are relative to oks positions, so bulk-copying a subrange
216    // would break Err(n) references that point outside the range. Use the default
217    // implementation which resolves each element via `get()` and re-pushes.
218
219    fn reserve_for<'a, I>(&mut self, selves: I) where Self: 'a, I: Iterator<Item = Self::Borrowed<'a>> + Clone {
220        self.inner.oks.reserve_for(selves.clone().map(|x| x.inner.oks));
221        self.inner.errs.reserve_for(selves.map(|x| x.inner.errs));
222    }
223}
224
225impl<TC: Clear, const N: u8> Clear for Lookbacks<TC, Vec<u8>, Vec<u64>, Vec<u64>, [u64; 2], N> {
226    fn clear(&mut self) {
227        self.inner.clear();
228    }
229}
230
231impl<'a, TC: crate::AsBytes<'a>, VC: crate::AsBytes<'a>, CC: crate::AsBytes<'a>, RC: crate::AsBytes<'a>> crate::AsBytes<'a> for Lookbacks<TC, VC, CC, RC, &'a [u64]> {
232    const SLICE_COUNT: usize = <Results<TC, VC, CC, RC, &'a [u64]> as crate::AsBytes<'a>>::SLICE_COUNT;
233    #[inline]
234    fn get_byte_slice(&self, index: usize) -> (u64, &'a [u8]) {
235        self.inner.get_byte_slice(index)
236    }
237}
238
239impl<'a, TC: crate::FromBytes<'a>, VC: crate::FromBytes<'a>, CC: crate::FromBytes<'a>, RC: crate::FromBytes<'a>> crate::FromBytes<'a> for Lookbacks<TC, VC, CC, RC, &'a [u64]> {
240    const SLICE_COUNT: usize = <Results<TC, VC, CC, RC, &'a [u64]>>::SLICE_COUNT;
241    #[inline(always)]
242    fn from_bytes(bytes: &mut impl Iterator<Item=&'a [u8]>) -> Self {
243        Self { inner: crate::FromBytes::from_bytes(bytes) }
244    }
245    #[inline(always)]
246    fn from_store(store: &crate::bytes::indexed::DecodedStore<'a>, offset: &mut usize) -> Self {
247        Self { inner: crate::FromBytes::from_store(store, offset) }
248    }
249    #[inline(always)]
250    fn element_sizes(sizes: &mut Vec<usize>) -> Result<(), String> {
251        <Results<TC, VC, CC, RC, &'a [u64]>>::element_sizes(sizes)
252    }
253}
254
255#[cfg(test)]
256mod test {
257
258    use alloc::vec::Vec;
259    use crate::common::{Push, Index, Len, Clear};
260    use crate::{Borrow, Container, AsBytes, FromBytes};
261    use crate::bytes::stash::Stash;
262    use super::{Repeats, Lookbacks};
263
264    /// Helper to populate a `Repeats<Vec<u64>>` from a slice.
265    fn repeats_from(values: &[u64]) -> Repeats<Vec<u64>> {
266        let mut repeats: Repeats<Vec<u64>> = Default::default();
267        for v in values {
268            repeats.push(v);
269        }
270        repeats
271    }
272
273    #[test]
274    fn push_and_index() {
275        let repeats = repeats_from(&[1, 1, 2, 2, 1]);
276
277        assert_eq!(repeats.len(), 5);
278        assert_eq!((&repeats).get(0), 1);
279        assert_eq!((&repeats).get(1), 1);
280        assert_eq!((&repeats).get(2), 2);
281        assert_eq!((&repeats).get(3), 2);
282        assert_eq!((&repeats).get(4), 1);
283
284        // Verify compression: only 3 distinct values stored (1, 2, 1).
285        assert_eq!(repeats.inner.somes.len(), 3);
286    }
287
288    #[test]
289    fn borrow_and_index() {
290        let mut repeats: Repeats<Vec<u64>> = Default::default();
291        for i in 0..50u64 {
292            repeats.push(&i);
293            repeats.push(&i); // repeat
294        }
295
296        assert_eq!(repeats.len(), 100);
297
298        let borrowed = repeats.borrow();
299        assert_eq!(borrowed.len(), 100);
300        for i in 0..50u64 {
301            assert_eq!(*borrowed.get(2 * i as usize), i);
302            assert_eq!(*borrowed.get(2 * i as usize + 1), i);
303        }
304    }
305
306    #[test]
307    fn ref_index() {
308        let repeats = repeats_from(&[10, 10, 20]);
309
310        assert_eq!((&repeats).get(0), 10u64);
311        assert_eq!((&repeats).get(1), 10u64);
312        assert_eq!((&repeats).get(2), 20u64);
313    }
314
315    #[test]
316    fn clear() {
317        let mut repeats = repeats_from(&[1, 2]);
318        assert_eq!(repeats.len(), 2);
319
320        repeats.clear();
321        assert_eq!(repeats.len(), 0);
322
323        repeats.push(&3u64);
324        assert_eq!(repeats.len(), 1);
325        assert_eq!((&repeats).get(0), 3);
326    }
327
328    #[test]
329    fn extend_from_self() {
330        let repeats = repeats_from(&[1, 1, 2, 3, 3]);
331
332        let mut dest: Repeats<Vec<u64>> = Default::default();
333        dest.extend_from_self(repeats.borrow(), 1..4);
334        assert_eq!(dest.len(), 3);
335        assert_eq!(*dest.borrow().get(0), 1);
336        assert_eq!(*dest.borrow().get(1), 2);
337        assert_eq!(*dest.borrow().get(2), 3);
338    }
339
340    #[test]
341    fn as_from_bytes() {
342        let mut repeats: Repeats<Vec<u64>> = Default::default();
343        for i in 0..100u64 {
344            repeats.push(&i);
345            repeats.push(&i);
346        }
347
348        let borrowed = repeats.borrow();
349        let rebuilt = Repeats::<&[u64], &[u64], &[u64], &[u64]>::from_bytes(
350            &mut borrowed.as_bytes().map(|(_, bytes)| bytes)
351        );
352        assert_eq!(rebuilt.len(), 200);
353        for i in 0..100u64 {
354            assert_eq!(*rebuilt.get(2 * i as usize), i);
355            assert_eq!(*rebuilt.get(2 * i as usize + 1), i);
356        }
357    }
358
359    #[test]
360    fn from_store_round_trip() {
361        let mut repeats: Repeats<Vec<u64>> = Default::default();
362        for i in 0..50u64 {
363            repeats.push(&i);
364            repeats.push(&i);
365        }
366
367        let mut store = Vec::new();
368        crate::bytes::indexed::encode(&mut store, &repeats.borrow());
369        let ds = crate::bytes::indexed::DecodedStore::new(&store);
370        let rebuilt = Repeats::<&[u64], &[u64], &[u64], &[u64]>::from_store(&ds, &mut 0);
371        assert_eq!(rebuilt.len(), 100);
372        for i in 0..50u64 {
373            assert_eq!(*rebuilt.get(2 * i as usize), i);
374            assert_eq!(*rebuilt.get(2 * i as usize + 1), i);
375        }
376    }
377
378    #[test]
379    fn validate_via_stash() {
380        let repeats = repeats_from(&[1, 1, 2, 2, 3]);
381
382        let mut bytes: Vec<u8> = Vec::new();
383        crate::bytes::indexed::write(&mut bytes, &repeats.borrow()).unwrap();
384        let stash: Stash<Repeats<Vec<u64>>, Vec<u8>> =
385            Stash::try_from_bytes(bytes).expect("Repeats<Vec<u64>> should validate");
386        let borrowed = stash.borrow();
387        assert_eq!(borrowed.len(), 5);
388        assert_eq!(*borrowed.get(0), 1);
389        assert_eq!(*borrowed.get(1), 1);
390        assert_eq!(*borrowed.get(2), 2);
391        assert_eq!(*borrowed.get(3), 2);
392        assert_eq!(*borrowed.get(4), 3);
393    }
394
395    #[test]
396    fn all_repeats() {
397        let mut repeats: Repeats<Vec<u64>> = Default::default();
398        for _ in 0..100 {
399            repeats.push(&42u64);
400        }
401        assert_eq!(repeats.len(), 100);
402        // Only one distinct value stored.
403        assert_eq!(repeats.inner.somes.len(), 1);
404
405        let borrowed = repeats.borrow();
406        for i in 0..100 {
407            assert_eq!(*borrowed.get(i), 42);
408        }
409    }
410
411    #[test]
412    fn no_repeats() {
413        let mut repeats: Repeats<Vec<u64>> = Default::default();
414        for i in 0..100u64 {
415            repeats.push(&i);
416        }
417        assert_eq!(repeats.len(), 100);
418        // Every value is distinct.
419        assert_eq!(repeats.inner.somes.len(), 100);
420
421        let borrowed = repeats.borrow();
422        for i in 0..100u64 {
423            assert_eq!(*borrowed.get(i as usize), i);
424        }
425    }
426
427    // --- Lookbacks tests ---
428
429    /// Helper to populate a `Lookbacks<Vec<u64>>` from a slice.
430    fn lookbacks_from(values: &[u64]) -> Lookbacks<Vec<u64>> {
431        let mut lookbacks: Lookbacks<Vec<u64>> = Default::default();
432        for v in values {
433            lookbacks.push(v);
434        }
435        lookbacks
436    }
437
438    #[test]
439    fn lookbacks_push_and_index() {
440        let lookbacks = lookbacks_from(&[10, 20, 10, 30, 20]);
441
442        assert_eq!(lookbacks.len(), 5);
443        assert_eq!((&lookbacks).get(0), 10);
444        assert_eq!((&lookbacks).get(1), 20);
445        assert_eq!((&lookbacks).get(2), 10);
446        assert_eq!((&lookbacks).get(3), 30);
447        assert_eq!((&lookbacks).get(4), 20);
448
449        // Values 10 and 20 at indices 2 and 4 should be lookbacks, not new oks.
450        assert_eq!(lookbacks.inner.oks.len(), 3);
451    }
452
453    #[test]
454    fn lookbacks_borrow_and_index() {
455        let mut lookbacks: Lookbacks<Vec<u64>> = Default::default();
456        for i in 0..50u64 {
457            lookbacks.push(&i);
458            lookbacks.push(&i); // lookback
459        }
460
461        assert_eq!(lookbacks.len(), 100);
462
463        let borrowed = lookbacks.borrow();
464        assert_eq!(borrowed.len(), 100);
465        for i in 0..50u64 {
466            assert_eq!(*borrowed.get(2 * i as usize), i);
467            assert_eq!(*borrowed.get(2 * i as usize + 1), i);
468        }
469    }
470
471    #[test]
472    fn lookbacks_clear() {
473        let mut lookbacks = lookbacks_from(&[1, 2]);
474        assert_eq!(lookbacks.len(), 2);
475
476        lookbacks.clear();
477        assert_eq!(lookbacks.len(), 0);
478
479        lookbacks.push(&3u64);
480        assert_eq!(lookbacks.len(), 1);
481        assert_eq!((&lookbacks).get(0), 3);
482    }
483
484    #[test]
485    fn lookbacks_extend_from_self() {
486        let lookbacks = lookbacks_from(&[10, 20, 30, 40, 50]);
487
488        let mut dest: Lookbacks<Vec<u64>> = Default::default();
489        dest.extend_from_self(lookbacks.borrow(), 1..4);
490        assert_eq!(dest.len(), 3);
491        assert_eq!(*dest.borrow().get(0), 20);
492        assert_eq!(*dest.borrow().get(1), 30);
493        assert_eq!(*dest.borrow().get(2), 40);
494    }
495
496    #[test]
497    fn lookbacks_as_from_bytes() {
498        let mut lookbacks: Lookbacks<Vec<u64>> = Default::default();
499        for i in 0..100u64 {
500            lookbacks.push(&i);
501            lookbacks.push(&i);
502        }
503
504        let borrowed = lookbacks.borrow();
505        let rebuilt = Lookbacks::<&[u64], &[u8], &[u64], &[u64], &[u64]>::from_bytes(
506            &mut borrowed.as_bytes().map(|(_, bytes)| bytes)
507        );
508        assert_eq!(rebuilt.len(), 200);
509        for i in 0..100u64 {
510            assert_eq!(*rebuilt.get(2 * i as usize), i);
511            assert_eq!(*rebuilt.get(2 * i as usize + 1), i);
512        }
513    }
514
515    #[test]
516    fn lookbacks_from_store_round_trip() {
517        let mut lookbacks: Lookbacks<Vec<u64>> = Default::default();
518        for i in 0..50u64 {
519            lookbacks.push(&i);
520            lookbacks.push(&i);
521        }
522
523        let mut store = Vec::new();
524        crate::bytes::indexed::encode(&mut store, &lookbacks.borrow());
525        let ds = crate::bytes::indexed::DecodedStore::new(&store);
526        let rebuilt = Lookbacks::<&[u64], &[u8], &[u64], &[u64], &[u64]>::from_store(&ds, &mut 0);
527        assert_eq!(rebuilt.len(), 100);
528        for i in 0..50u64 {
529            assert_eq!(*rebuilt.get(2 * i as usize), i);
530            assert_eq!(*rebuilt.get(2 * i as usize + 1), i);
531        }
532    }
533
534    #[test]
535    fn lookbacks_validate_via_stash() {
536        let lookbacks = lookbacks_from(&[1, 2, 1, 3, 2]);
537
538        let mut bytes: Vec<u8> = Vec::new();
539        crate::bytes::indexed::write(&mut bytes, &lookbacks.borrow()).unwrap();
540        let stash: Stash<Lookbacks<Vec<u64>>, Vec<u8>> =
541            Stash::try_from_bytes(bytes).expect("Lookbacks<Vec<u64>> should validate");
542        let borrowed = stash.borrow();
543        assert_eq!(borrowed.len(), 5);
544        assert_eq!(*borrowed.get(0), 1);
545        assert_eq!(*borrowed.get(1), 2);
546        assert_eq!(*borrowed.get(2), 1);
547        assert_eq!(*borrowed.get(3), 3);
548        assert_eq!(*borrowed.get(4), 2);
549    }
550
551    #[test]
552    fn lookbacks_all_same() {
553        let mut lookbacks: Lookbacks<Vec<u64>> = Default::default();
554        for _ in 0..100 {
555            lookbacks.push(&42u64);
556        }
557        assert_eq!(lookbacks.len(), 100);
558        // Only the first value is stored as Ok; rest are Err lookbacks.
559        assert_eq!(lookbacks.inner.oks.len(), 1);
560
561        let borrowed = lookbacks.borrow();
562        for i in 0..100 {
563            assert_eq!(*borrowed.get(i), 42);
564        }
565    }
566
567    #[test]
568    fn lookbacks_no_matches() {
569        let mut lookbacks: Lookbacks<Vec<u64>> = Default::default();
570        for i in 0..100u64 {
571            lookbacks.push(&(i * 1000)); // all distinct, spaced far apart
572        }
573        assert_eq!(lookbacks.len(), 100);
574        // Every value is unique; all stored as Ok.
575        assert_eq!(lookbacks.inner.oks.len(), 100);
576
577        let borrowed = lookbacks.borrow();
578        for i in 0..100u64 {
579            assert_eq!(*borrowed.get(i as usize), i * 1000);
580        }
581    }
582}