1use std::{io, iter::FusedIterator, ops::{Deref, DerefMut}};
4
5use binout::{AsIs, Serializer};
6use bitm::{ceiling_div, n_lowest_bits, RankSelect101111, BitAccess, BitVec, CombinedSampling, ConstCombinedSamplingDensity, Rank, Select, Select0, Select0ForRank101111, SelectForRank101111};
7use dyn_size_of::GetSize;
8
9pub struct Builder<BV = Box<[u64]>> {
13 hi: BV, lo: Box<[u64]>, bits_per_lo: u8, current_len: usize, target_len: usize, last_added: u64, universe: u64 }
21
22impl<BV> Builder<BV> {
23 #[inline] pub fn universe(&self) -> u64 { self.universe }
25
26 #[inline] pub fn current_len(&self) -> usize { self.current_len }
28
29 #[inline] pub fn target_len(&self) -> usize { self.target_len }
31
32 #[inline] pub fn last_pushed(&self) -> u64 { self.last_added }
34}
35
36impl<BV: BitVec> Builder<BV> {
37 pub fn new_b(final_len: usize, universe: u64) -> Self {
42 if final_len == 0 || universe == 0 {
43 return Self { hi: BV::with_64bit_segments(0, 0), lo: Default::default(), bits_per_lo: 0, current_len: 0, target_len: 0, last_added: 0, universe };
44 }
45 let bits_per_lo = (universe / final_len as u64).checked_ilog2().unwrap_or(0) as u8;
46 Self {
47 hi: BV::with_zeroed_bits(final_len + ((universe-1) >> bits_per_lo) as usize),
49 lo: Box::with_zeroed_bits(1.max(final_len * bits_per_lo as usize)),
50 bits_per_lo,
51 current_len: 0,
52 target_len: final_len,
53 last_added: 0,
54 universe,
55 }
56 }
57}
58
59impl Builder {
60 #[inline] pub fn new(final_len: usize, universe: u64) -> Self {
64 Self::new_b(final_len, universe)
65 }
66}
67
68impl<BV: DerefMut<Target = [u64]>> Builder<BV> {
69 pub unsafe fn push_unchecked(&mut self, value: u64) {
71 self.hi.set_bit((value>>self.bits_per_lo) as usize + self.current_len);
72 self.lo.init_successive_fragment(&mut self.current_len, value & n_lowest_bits(self.bits_per_lo), self.bits_per_lo);
73 self.last_added = value;
74 }
75
76 pub unsafe fn push_diff_unchecked(&mut self, diff: u64) {
79 self.push_unchecked(self.last_added+diff)
80 }
81
82 pub fn push(&mut self, value: u64) {
85 assert!(value < self.universe, "Elias-Fano Builder: cannot push value {value} outside the universe (<{})", self.universe);
86 assert!(self.current_len < self.target_len, "Elias-Fano Builder: push exceeds the declared length of {} values", self.target_len);
87 assert!(self.last_added <= value, "Elias-Fano Builder: values must be pushed in non-decreasing order, but received {value} after {}", self.last_added);
88 unsafe { self.push_unchecked(value) }
89 }
90
91 pub fn push_diff(&mut self, diff: u64) {
94 self.push(self.last_added.saturating_add(diff))
95 }
96
97 pub fn push_all<I: IntoIterator<Item = u64>>(&mut self, values: I) {
99 for value in values { self.push(value) }
100 }
101
102 pub fn push_diffs<I: IntoIterator<Item = u64>>(&mut self, diffs: I) {
104 for diff in diffs { self.push_diff(diff) }
105 }
106}
107
108impl<BV: Deref<Target = [u64]>> Builder<BV> {
109 pub fn finish_unchecked_s<S: SelectForRank101111, S0: Select0ForRank101111>(self) -> Sequence<S, S0, BV> {
112 Sequence::<S, S0, BV> {
113 hi: self.hi.into(),
114 lo: self.lo,
115 bits_per_lo: self.bits_per_lo,
116 len: self.current_len,
117 }
118 }
119
120 pub fn finish_s<S: SelectForRank101111, S0: Select0ForRank101111>(self) -> Sequence<S, S0, BV> {
123 assert_eq!(self.current_len, self.target_len, "Cannot finish building Elias-Fano Sequence as the current length ({}) differs from the target ({})", self.current_len, self.target_len);
124 self.finish_unchecked_s::<S, S0>()
125 }
126
127 #[inline] pub fn finish_unchecked(self) -> Sequence<DefaultSelectStrategy, DefaultSelectStrategy, BV> {
130 self.finish_unchecked_s()
131 }
132
133 #[inline] pub fn finish(self) -> Sequence<DefaultSelectStrategy, DefaultSelectStrategy, BV> {
136 self.finish_s()
137 }
138}
139
140pub type DefaultSelectStrategy = CombinedSampling<ConstCombinedSamplingDensity>;
142
143pub struct Sequence<S = DefaultSelectStrategy, S0 = DefaultSelectStrategy, BV=Box<[u64]>> {
166 hi: RankSelect101111<S, S0, BV>, lo: Box<[u64]>, bits_per_lo: u8, len: usize }
171
172impl<S, S0, BV> Sequence<S, S0, BV> {
173 #[inline] pub fn len(&self) -> usize { self.len }
175
176 #[inline] pub fn is_empty(&self) -> bool { self.len == 0 }
178
179 #[inline] pub fn bits_per_lo(&self) -> u8 { self.bits_per_lo }
180}
181
182impl<S, S0, BV: Deref<Target = [u64]>> Sequence<S, S0, BV> {
183 #[inline] unsafe fn advance_position_unchecked(&self, position: &mut Position) {
185 position.lo += 1;
186 position.hi = if position.lo != self.len {
187 self.hi.content.find_bit_one_unchecked(position.hi+1)
188 } else {
189 self.hi.content.len() * 64
190 }
191 }
192
193 #[inline] unsafe fn advance_position_back_unchecked(&self, position: &mut Position) {
195 position.lo -= 1;
196 position.hi = self.hi.content.rfind_bit_one_unchecked(position.hi-1);
197 }
198
199 #[inline] unsafe fn position_next_unchecked(&self, position: &mut Position) -> u64 {
201 let result = self.value_at_position_unchecked(*position);
202 self.advance_position_unchecked(position);
203 result
204 }
205
206 #[inline] fn position_next(&self, position: &mut Position) -> Option<u64> {
208 (position.lo != self.len).then(|| unsafe { self.position_next_unchecked(position) })
209 }
210
211 #[inline] unsafe fn value_at_position_unchecked(&self, position: Position) -> u64 {
212 position.hi_bits() << self.bits_per_lo | self.lo.get_fragment(position.lo, self.bits_per_lo)
213 }
214
215 #[inline] unsafe fn diff_at_position_unchecked(&self, mut position: Position) -> u64 {
218 let current = self.value_at_position_unchecked(position);
219 if position.lo == 0 { return current; }
220 self.advance_position_back_unchecked(&mut position);
221 current - self.value_at_position_unchecked(position)
222 }
223
224 #[inline] fn diff_at_position(&self, position: Position) -> Option<u64> {
227 (position.lo != self.len).then(|| unsafe { self.diff_at_position_unchecked(position) })
228 }
229
230 #[inline] fn value_at_position(&self, position: Position) -> Option<u64> {
232 (position.lo != self.len).then(|| unsafe { self.value_at_position_unchecked(position) })
233 }
234
235 #[inline] fn begin_position(&self) -> Position {
237 Position { hi: self.hi.content.trailing_zero_bits(), lo: 0 }
238 }
239
240 #[inline] fn end_position(&self) -> Position {
242 Position { hi: self.hi.content.len() * 64, lo: self.len }
243 }
244
245 #[inline] fn cursor(&'_ self, position: Position) -> Cursor<'_, S, S0, BV> {
247 Cursor { sequence: &self, position }
248 }
249
250 #[inline] pub fn iter(&'_ self) -> Iterator<'_, S, S0, BV> {
252 Iterator { sequence: self, begin: self.begin_position(), end: self.end_position() }
253 }
254
255 #[inline] pub fn diffs(&'_ self) -> DiffIterator<'_, S, S0, BV> {
258 DiffIterator { sequence: self, position: self.begin_position(), prev_value: 0 }
259 }
260
261 #[inline] pub fn begin(&'_ self) -> Cursor<'_, S, S0, BV> {
263 self.cursor(self.begin_position())
264 }
265
266 #[inline] pub fn end(&'_ self) -> Cursor<'_, S, S0, BV> {
268 self.cursor(self.end_position())
269 }
270
271 pub fn write_bytes(&self) -> usize {
273 AsIs::size(self.bits_per_lo) +
274 AsIs::array_size(&self.hi.content) +
275 if self.bits_per_lo != 0 && self.len != 0 { AsIs::array_content_size(&self.lo) } else { 0 }
276 }
277
278 pub fn write(&self, output: &mut dyn io::Write) -> io::Result<()>
280 {
281 AsIs::write(output, self.bits_per_lo)?;
282 AsIs::write_array(output, &self.hi.content)?;
283 if self.bits_per_lo != 0 && self.len != 0 { AsIs::write_all(output, self.lo.iter())? };
284 Ok(())
285 }
286}
287
288impl Sequence {
289 #[inline] pub fn with_items_from_slice<I: Into<u64> + Clone>(items: &[I]) -> Self {
291 Self::with_items_from_slice_s(items)
292 }
293
294 pub fn read(input: &mut dyn io::Read) -> io::Result<Self> {
296 Self::read_s(input)
297 }
298}
299
300impl<S: SelectForRank101111, S0: Select0ForRank101111, BV: Deref<Target = [u64]>+FromIterator<u64>> Sequence<S, S0, BV> {
301
302 pub fn read_s(input: &mut dyn io::Read) -> io::Result<Self> {
306 let bits_per_lo: u8 = AsIs::read(input)?;
307 let hi: BV = <AsIs as Serializer<u64>>::read_array_iter(input)?.collect::<io::Result<BV>>()?;
308 let (hi, len) = RankSelect101111::build(hi);
309 let lo = if bits_per_lo != 0 && len != 0 {
310 AsIs::read_n(input, ceiling_div(len * bits_per_lo as usize, 64))?
311 } else {
312 (if len == 0 { vec![] } else { vec![0] }).into_boxed_slice()
313 };
314 Ok(Self { hi, lo, bits_per_lo, len })
315 }
316}
317
318impl<S: SelectForRank101111, S0: Select0ForRank101111, BV: BitVec+DerefMut<Target = [u64]>> Sequence<S, S0, BV> {
319 pub fn with_items_from_slice_s<I: Into<u64> + Clone>(items: &[I]) -> Self {
322 let mut b = Builder::<BV>::new_b(items.len(), items.last().map_or(0, |v| v.clone().into()+1));
323 b.push_all(items.iter().map(|v| v.clone().into()));
324 b.finish_unchecked_s()
325 }
326}
327
328impl<S: SelectForRank101111, S0, BV: Deref<Target = [u64]>> Sequence<S, S0, BV> {
329 #[inline] pub unsafe fn get_unchecked(&self, index: usize) -> u64 {
331 (((unsafe{self.hi.select_unchecked(index)} - index) as u64) << self.bits_per_lo) |
332 self.lo.get_fragment(index, self.bits_per_lo)
333 }
334
335 #[inline] pub fn get(&self, index: usize) -> Option<u64> {
337 (index < self.len).then(|| unsafe{self.get_unchecked(index)} )
338 }
339
340 pub fn get_or_panic(&self, index: usize) -> u64 {
342 self.get(index).expect("attempt to retrieve value for an index out of bounds of the Elias-Fano Sequence")
343 }
344
345 #[inline] pub unsafe fn diff_unchecked(&self, index: usize) -> u64 {
349 self.diff_at_position_unchecked(self.position_at_unchecked(index))
350 }
351
352 #[inline] pub fn diff(&self, index: usize) -> Option<u64> {
356 (index < self.len).then(|| unsafe{self.diff_unchecked(index)})
357 }
358
359 #[inline] pub fn diff_or_panic(&self, index: usize) -> u64 {
363 self.diff(index).expect("attempt to retrieve diff for an index out of bounds of the Elias-Fano Sequence")
364 }
365
366 #[inline] unsafe fn position_at_unchecked(&self, index: usize) -> Position {
367 Position { hi: self.hi.select_unchecked(index), lo: index }
368 }
369
370 #[inline] pub unsafe fn cursor_at_unchecked(&'_ self, index: usize) -> Cursor<'_, S, S0, BV> {
377 self.cursor(self.position_at_unchecked(index))
378 }
379
380 #[inline] pub unsafe fn cursor_at(&'_ self, index: usize) -> Option<Cursor<'_, S, S0, BV>> {
383 (index < self.len).then(|| unsafe { self.cursor_at_unchecked(index) })
384 }
385}
386
387impl<S, S0: Select0ForRank101111, BV: Deref<Target = [u64]>> Sequence<S, S0, BV> {
388 fn geq_position_uncorrected(&self, value: u64) -> Position {
392 let value_hi = (value >> self.bits_per_lo) as usize;
393 let mut hi_index = self.hi.try_select0(value_hi).unwrap_or_else(|| self.hi.content.len() * 64); let mut lo_index = hi_index - value_hi;
396
397 let value_lo = value as u64 & n_lowest_bits(self.bits_per_lo);
398 while lo_index > 0 && self.hi.content.get_bit(hi_index - 1) &&
400 value_lo <= self.lo.get_fragment(lo_index-1, self.bits_per_lo)
401 {
402 lo_index -= 1;
403 hi_index -= 1;
404 }
405 Position { hi: hi_index, lo: lo_index }
406 }
407
408 fn geq_position(&self, value: u64) -> Position {
410 let mut result = self.geq_position_uncorrected(value);
411 result.hi = self.hi.content.find_bit_one(result.hi).unwrap_or_else(|| self.hi.content.len() * 64);
412 result
413 }
414
415 fn position_of(&self, value: u64) -> Option<Position> {
416 let geq_position = self.geq_position(value);
417 self.value_at_position(geq_position).and_then(|geq_value| (geq_value==value).then_some(geq_position))
418 }
419
420 #[inline] pub fn geq_cursor(&'_ self, value: u64) -> Cursor<'_, S, S0, BV> {
422 self.cursor(self.geq_position(value))
423 }
424
425 #[inline] pub fn geq_index(&self, value: u64) -> usize {
427 self.geq_position_uncorrected(value).lo
428 }
429
430 #[inline] pub fn cursor_of(&'_ self, value: u64) -> Option<Cursor<'_, S, S0, BV>> {
432 self.position_of(value).map(|position| self.cursor(position))
433 }
434
435 #[inline] pub fn index_of(&self, value: u64) -> Option<usize> {
437 self.position_of(value).map(|p| p.lo)
438 }
439}
440
441impl<S: SelectForRank101111, S0, BV: Deref<Target = [u64]>> Select for Sequence<S, S0, BV> {
442 #[inline] unsafe fn select_unchecked(&self, rank: usize) -> usize {
443 self.get_unchecked(rank) as usize
444 }
445
446 #[inline] fn try_select(&self, rank: usize) -> Option<usize> {
447 self.get(rank).map(|v| v as usize)
448 }
449}
450
451impl<S, S0: Select0ForRank101111, BV: Deref<Target = [u64]>> Rank for Sequence<S, S0, BV> {
452 #[inline] unsafe fn rank_unchecked(&self, value: usize) -> usize {
454 self.geq_index(value as u64)
455 }
456
457 #[inline] fn try_rank(&self, value: usize) -> Option<usize> {
459 Some(self.geq_index(value as u64))
460 }
461}
462
463impl<S, S0, BV> GetSize for Sequence<S, S0, BV> where RankSelect101111<S, S0, BV>: GetSize {
464 fn size_bytes_dyn(&self) -> usize { self.lo.size_bytes_dyn() + self.hi.size_bytes_dyn() }
465 const USES_DYN_MEM: bool = true;
466}
467
468impl<'ef, S, S0, BV: Deref<Target = [u64]>> IntoIterator for &'ef Sequence<S, S0, BV> {
469 type Item = u64;
470 type IntoIter = Iterator<'ef, S, S0, BV>;
471 #[inline] fn into_iter(self) -> Self::IntoIter { self.iter() }
472}
473
474#[derive(Clone, Copy)]
477struct Position {
478 hi: usize,
479 lo: usize
480}
481
482impl Position {
483 #[inline(always)] fn hi_bits(&self) -> u64 { (self.hi - self.lo) as u64 }
484}
485
486pub struct Iterator<'ef, S, S0, BV> {
488 sequence: &'ef Sequence<S, S0, BV>,
489 begin: Position,
490 end: Position
491}
492
493impl<S, S0, BV> Iterator<'_, S, S0, BV> {
494 pub fn sequence(&self) -> &Sequence<S, S0, BV> { self.sequence }
496
497 pub fn index(&self) -> usize { self.begin.lo }
499
500 pub fn back_index(&self) -> usize { self.begin.lo }
502}
503
504impl<S, S0, BV: Deref<Target = [u64]>> std::iter::Iterator for Iterator<'_, S, S0, BV> {
505 type Item = u64;
506
507 fn next(&mut self) -> Option<Self::Item> {
508 (self.begin.lo != self.end.lo).then(|| unsafe { self.sequence.position_next_unchecked(&mut self.begin) })
509 }
510}
511
512impl<S, S0, BV: Deref<Target = [u64]>> DoubleEndedIterator for Iterator<'_, S, S0, BV> {
513 fn next_back(&mut self) -> Option<Self::Item> {
514 (self.begin.lo != self.end.lo).then(|| unsafe {
515 self.sequence.advance_position_back_unchecked(&mut self.end);
516 self.sequence.value_at_position_unchecked(self.end)
517 })
518 }
519}
520
521impl<S, S0, BV: Deref<Target = [u64]>> FusedIterator for Iterator<'_, S, S0, BV> {}
522
523pub struct DiffIterator<'ef, S, S0, BV> {
526 sequence: &'ef Sequence<S, S0, BV>,
527 position: Position,
528 prev_value: u64
529}
530
531impl<S, S0, BV> DiffIterator<'_, S, S0, BV> {
532 pub fn sequence(&self) -> &Sequence<S, S0, BV> { self.sequence }
534
535 pub fn index(&self) -> usize { self.position.lo }
537}
538
539impl<S, S0, BV: Deref<Target = [u64]>> std::iter::Iterator for DiffIterator<'_, S, S0, BV> {
540 type Item = u64;
541
542 fn next(&mut self) -> Option<Self::Item> {
543 let current_value = self.sequence.position_next(&mut self.position)?;
544 let result = current_value - self.prev_value;
545 self.prev_value = current_value;
546 Some(result)
547 }
548}
549
550impl<S, S0, BV: Deref<Target = [u64]>> FusedIterator for DiffIterator<'_, S, S0, BV> {}
551
552#[derive(Clone, Copy)]
555pub struct Cursor<'ef, S, S0, BV> {
556 sequence: &'ef Sequence<S, S0, BV>,
557 position: Position,
558}
559
560impl<S, S0, BV> Cursor<'_, S, S0, BV> {
561 pub fn sequence(&self) -> &Sequence<S, S0, BV> { self.sequence }
563
564 #[inline] pub fn is_end(&self) -> bool { self.position.lo == self.sequence.len }
566
567 #[inline] pub fn is_valid(&self) -> bool { self.position.lo != self.sequence.len }
569
570 #[inline] pub fn index(&self) -> usize { self.position.lo }
572}
573
574impl<S, S0, BV: Deref<Target = [u64]>> Cursor<'_, S, S0, BV> {
575 #[inline] pub unsafe fn value_unchecked(&self) -> u64 {
577 return self.sequence.value_at_position_unchecked(self.position)
578 }
579
580 #[inline] pub fn value(&self) -> Option<u64> {
582 return self.sequence.value_at_position(self.position)
583 }
584
585 #[inline] pub fn advance(&mut self) -> bool {
587 if self.is_end() { return false; }
588 unsafe { self.sequence.advance_position_unchecked(&mut self.position) };
589 true
590 }
591
592 #[inline] pub fn advance_back(&mut self) -> bool {
594 if self.position.lo == 0 { return false; }
595 unsafe { self.sequence.advance_position_back_unchecked(&mut self.position) };
596 true
597 }
598
599 pub fn next_back(&mut self) -> Option<u64> {
601 (self.position.lo != 0).then(|| unsafe {
602 self.sequence.advance_position_back_unchecked(&mut self.position);
603 self.sequence.value_at_position_unchecked(self.position)
604 })
605 }
606
607 #[inline] pub unsafe fn diff_unchecked(&self) -> u64 {
610 self.sequence.diff_at_position_unchecked(self.position)
611 }
612
613 #[inline] pub fn diff(&self) -> Option<u64> {
616 self.sequence.diff_at_position(self.position)
617 }
618
619 #[inline] pub fn diffs(&self) -> DiffIterator<'_, S, S0, BV> {
622 if self.position.lo == 0 { return self.sequence.diffs(); }
623 let mut prev = self.position;
624 unsafe{self.sequence.advance_position_back_unchecked(&mut prev)};
625 DiffIterator { sequence: self.sequence, position: self.position, prev_value: unsafe{self.sequence.value_at_position_unchecked(prev)} }
626 }
627}
628
629impl<S, S0, BV: Deref<Target = [u64]>> std::iter::Iterator for Cursor<'_, S, S0, BV> {
630 type Item = u64;
631
632 fn next(&mut self) -> Option<Self::Item> {
634 self.sequence.position_next(&mut self.position)
635 }
636}
637
638impl<S, S0, BV: Deref<Target = [u64]>> FusedIterator for Cursor<'_, S, S0, BV> {}
639
640
641#[cfg(test)]
642mod tests {
643 use bitm::BinaryRankSearch;
644
645 use super::*;
646
647 fn test_read_write<S: SelectForRank101111, S0: Select0ForRank101111>(seq: Sequence<S, S0>) {
648 let mut buff = Vec::new();
649 seq.write(&mut buff).unwrap();
650 assert_eq!(buff.len(), seq.write_bytes());
651 let read = Sequence::<S, S0>::read_s(&mut &buff[..]).unwrap();
652 assert_eq!(seq.len, read.len);
653 assert_eq!(seq.hi.content, read.hi.content);
654 assert_eq!(seq.lo, read.lo);
655 }
656
657 #[test]
658 fn test_empty() {
659 let ef = Builder::new(0, 0).finish();
660 assert_eq!(ef.get(0), None);
661 assert_eq!(ef.rank(0), 0);
662 assert_eq!(ef.iter().collect::<Vec<_>>(), []);
663 assert_eq!(ef.iter().rev().collect::<Vec<_>>(), []);
664 test_read_write(ef);
665 }
666
667 #[test]
668 fn test_small_sparse() {
669 let mut ef = Builder::new(5, 1000);
670 ef.push(0);
671 ef.push(1);
672 ef.push(801);
673 ef.push(920);
674 ef.push(999);
675 let ef = ef.finish_s::<BinaryRankSearch, BinaryRankSearch>();
676 assert_eq!(ef.get(0), Some(0));
677 assert_eq!(ef.get(1), Some(1));
678 assert_eq!(ef.get(2), Some(801));
679 assert_eq!(ef.get(3), Some(920));
680 assert_eq!(ef.get(4), Some(999));
681 assert_eq!(ef.get(5), None);
682 assert_eq!(ef.iter().collect::<Vec<_>>(), [0, 1, 801, 920, 999]);
683 assert_eq!(ef.iter().rev().collect::<Vec<_>>(), [999, 920, 801, 1, 0]);
684 assert_eq!(ef.geq_cursor(801).collect::<Vec<_>>(), [801, 920, 999]);
685 assert_eq!(ef.geq_cursor(802).collect::<Vec<_>>(), [920, 999]);
686 assert_eq!(ef.rank(0), 0);
687 assert_eq!(ef.rank(1), 1);
688 assert_eq!(ef.rank(2), 2);
689 assert_eq!(ef.rank(800), 2);
690 assert_eq!(ef.rank(801), 2);
691 assert_eq!(ef.rank(802), 3);
692 assert_eq!(ef.rank(920), 3);
693 assert_eq!(ef.rank(921), 4);
694 assert_eq!(ef.rank(999), 4);
695 assert_eq!(ef.rank(1000), 5);
696 let mut c = ef.cursor_of(920).unwrap();
697 assert_eq!(c.index(), 3);
698 assert_eq!(c.value(), Some(920));
699 c.advance();
700 assert_eq!(c.index(), 4);
701 assert_eq!(c.value(), Some(999));
702 c.advance();
703 assert_eq!(c.index(), 5);
704 assert_eq!(c.value(), None);
705 test_read_write(ef);
706 }
707
708 #[test]
709 fn test_small_dense() {
710 let mut ef = Builder::new(5, 6);
711 ef.push(0);
712 ef.push(1);
713 ef.push(3);
714 ef.push(3);
715 ef.push(5);
716 let ef: Sequence = ef.finish();
717 assert_eq!(ef.get(0), Some(0));
718 assert_eq!(ef.get(1), Some(1));
719 assert_eq!(ef.get(2), Some(3));
720 assert_eq!(ef.get(3), Some(3));
721 assert_eq!(ef.get(4), Some(5));
722 assert_eq!(ef.get(5), None);
723 assert_eq!(ef.iter().collect::<Vec<_>>(), [0, 1, 3, 3, 5]);
724 assert_eq!(ef.geq_cursor(3).collect::<Vec<_>>(), [3, 3, 5]);
725 assert_eq!(ef.geq_cursor(10).collect::<Vec<_>>(), []);
726 assert_eq!(ef.iter().rev().collect::<Vec<_>>(), [5, 3, 3, 1, 0]);
727 assert_eq!(ef.rank(0), 0);
728 assert_eq!(ef.rank(1), 1);
729 assert_eq!(ef.rank(2), 2);
730 assert_eq!(ef.rank(3), 2);
731 assert_eq!(ef.rank(4), 4);
732 assert_eq!(ef.rank(5), 4);
733 assert_eq!(ef.rank(6), 5);
734 assert_eq!(ef.diff(0), Some(0));
735 assert_eq!(ef.diff(1), Some(1));
736 assert_eq!(ef.diff(2), Some(2));
737 assert_eq!(ef.diff(3), Some(0));
738 assert_eq!(ef.diff(4), Some(2));
739 assert_eq!(ef.diff(5), None);
740 assert_eq!(ef.diffs().collect::<Vec<_>>(), [0, 1, 2, 0, 2]);
741 assert_eq!(ef.geq_cursor(3).diffs().collect::<Vec<_>>(), [2, 0, 2]);
742 test_read_write(ef);
743 }
744
745 #[test]
746 fn test_mid_1() {
747 let mut ef = Builder::new(1<<16, 1<<16);
748 ef.push_all(0..1<<16);
749 let ef: Sequence = ef.finish();
750 for i in (1..1<<16).step_by(33) {
751 assert_eq!(ef.get(i), Some(i as u64));
752 assert_eq!(ef.diff(i), Some(1));
753 assert_eq!(ef.index_of(i as u64), Some(i));
754 assert_eq!(ef.geq_index(i as u64), i);
755 }
756 test_read_write(ef);
757 }
758
759 #[test]
760 fn test_mid_3() {
761 let mut ef = Builder::new(1<<16, (1<<16)*3 + 1);
762 ef.push_all((1..=1<<16).map(|v|v*3)); let ef: Sequence = ef.finish();
764 for i in (1usize..1<<16).step_by(33) {
765 let value = (i as u64 + 1) * 3;
766 assert_eq!(ef.get(i), Some(value), "get({}) should be {}", i, value);
767 assert_eq!(ef.diff(i), Some(3));
768 assert_eq!(ef.index_of(value), Some(i));
769 assert_eq!(ef.geq_index(value), i);
770 }
771 test_read_write(ef);
772 }
773
774 #[cfg(target_pointer_width = "64")]
775 #[test]
776 #[ignore = "uses much memory and time"]
777 fn test_huge() {
778 let mut ef = Builder::new(1<<33, (1<<33)/2 + 1);
779 ef.push_all((1..=1<<33).map(|v|v/2));
780 let ef: Sequence = ef.finish();
781 let mut prev_value = 0;
782 for i in (1<<33)-2050..1<<33 {
783 let value = (i as u64 + 1) / 2;
784 assert_eq!(ef.get(i), Some(value));
785 if prev_value != 0 {
786 if value != prev_value {
787 assert_eq!(ef.index_of(value), Some(i));
788 assert_eq!(ef.geq_index(value), i);
789 }
790 assert_eq!(ef.diff(i), Some(value-prev_value));
791 }
792 prev_value = value;
793 }
794 test_read_write(ef);
795 }
796}