1use crate::bucket::{BucketCell, BucketIApi, BucketRwIApi};
2use crate::common::page::tree::branch::MappedBranchPage;
3use crate::common::page::tree::leaf::{MappedLeafPage, BUCKET_LEAF_FLAG};
4use crate::common::page::tree::TreePage;
5use crate::common::page::{CoerciblePage, RefPage};
6use crate::common::{BVec, PgId, SplitRef};
7use crate::node::NodeRwCell;
8use crate::Error::IncompatibleValue;
9use bumpalo::Bump;
10use std::marker::PhantomData;
11
12pub trait CursorApi {
14 fn first(&mut self) -> Option<(&[u8], Option<&[u8]>)>;
44
45 fn last(&mut self) -> Option<(&[u8], Option<&[u8]>)>;
75
76 fn next(&mut self) -> Option<(&[u8], Option<&[u8]>)>;
107
108 fn prev(&mut self) -> Option<(&[u8], Option<&[u8]>)>;
138
139 fn seek<T: AsRef<[u8]>>(&mut self, seek: T) -> Option<(&[u8], Option<&[u8]>)>;
170}
171
172pub trait CursorRwApi: CursorApi {
174 fn delete(&mut self) -> crate::Result<()>;
210}
211
212pub struct CursorImpl<'tx: 'a, 'a> {
215 pub(crate) c: InnerCursor<'tx>,
216 p: PhantomData<&'a u8>,
217}
218
219impl<'tx: 'a, 'a> From<InnerCursor<'tx>> for CursorImpl<'tx, 'a> {
220 fn from(value: InnerCursor<'tx>) -> Self {
221 CursorImpl {
222 c: value,
223 p: PhantomData,
224 }
225 }
226}
227
228impl<'tx: 'a, 'a> CursorApi for CursorImpl<'tx, 'a> {
229 fn first(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
230 self.c.api_first()
231 }
232
233 fn last(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
234 self.c.api_last()
235 }
236
237 fn next(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
238 self.c.api_next()
239 }
240
241 fn prev(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
242 self.c.api_prev()
243 }
244
245 fn seek<T: AsRef<[u8]>>(&mut self, seek: T) -> Option<(&[u8], Option<&[u8]>)> {
246 self.c.api_seek(seek.as_ref())
247 }
248}
249
250pub struct CursorRwImpl<'tx: 'a, 'a> {
252 c: InnerCursor<'tx>,
253 p: PhantomData<&'a u8>,
254}
255
256impl<'tx: 'a, 'a> CursorRwImpl<'tx, 'a> {
257 pub(crate) fn new(c: InnerCursor<'tx>) -> Self {
258 CursorRwImpl { c, p: PhantomData }
259 }
260}
261
262impl<'tx: 'a, 'a> From<InnerCursor<'tx>> for CursorRwImpl<'tx, 'a> {
263 fn from(value: InnerCursor<'tx>) -> Self {
264 CursorRwImpl::new(value)
265 }
266}
267
268impl<'tx: 'a, 'a> CursorApi for CursorRwImpl<'tx, 'a> {
269 fn first(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
270 self.c.api_first()
271 }
272
273 fn last(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
274 self.c.api_last()
275 }
276
277 fn next(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
278 self.c.api_next()
279 }
280
281 fn prev(&mut self) -> Option<(&[u8], Option<&[u8]>)> {
282 self.c.api_prev()
283 }
284
285 fn seek<T: AsRef<[u8]>>(&mut self, seek: T) -> Option<(&[u8], Option<&[u8]>)> {
286 self.c.api_seek(seek.as_ref())
287 }
288}
289
290impl<'tx: 'a, 'a> CursorRwApi for CursorRwImpl<'tx, 'a> {
291 fn delete(&mut self) -> crate::Result<()> {
292 self.c.api_delete()
293 }
294}
295
296pub(crate) trait CursorIApi<'tx>: Clone {
297 fn api_first(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)>;
299
300 fn i_first(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)>;
301
302 fn api_next(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)>;
304
305 fn i_next(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)>;
308
309 fn api_prev(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)>;
311
312 fn i_prev(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)>;
315
316 fn api_last(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)>;
318
319 fn i_last(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)>;
321
322 fn key_value(&self) -> Option<(&'tx [u8], &'tx [u8], u32)>;
324
325 fn api_seek(&mut self, seek: &[u8]) -> Option<(&'tx [u8], Option<&'tx [u8]>)>;
327
328 fn i_seek(&mut self, seek: &[u8]) -> Option<(&'tx [u8], &'tx [u8], u32)>;
331
332 fn go_to_first_element_on_the_stack(&mut self);
334
335 fn search(&mut self, key: &[u8], pgid: PgId);
337
338 fn search_inodes(&mut self, key: &[u8]);
339
340 fn search_node(&mut self, key: &[u8], node: NodeRwCell<'tx>);
341
342 fn search_page(&mut self, key: &[u8], page: &RefPage);
343}
344
345pub(crate) trait CursorRwIApi<'tx>: CursorIApi<'tx> {
346 fn node(&mut self) -> NodeRwCell<'tx>;
348
349 fn api_delete(&mut self) -> crate::Result<()>;
351}
352
353#[derive(Copy, Clone, Eq, PartialEq)]
354pub enum PageNode<'tx> {
355 Page(RefPage<'tx>),
356 Node(NodeRwCell<'tx>),
357}
358
359#[derive(Clone, Eq, PartialEq)]
360pub struct ElemRef<'tx> {
361 pn: PageNode<'tx>,
362 index: i32,
363}
364
365impl<'tx> ElemRef<'tx> {
366 fn count(&self) -> u32 {
368 match &self.pn {
369 PageNode::Page(r) => r.count as u32,
370 PageNode::Node(n) => n.cell.borrow().inodes.len() as u32,
371 }
372 }
373
374 fn is_leaf(&self) -> bool {
376 match &self.pn {
377 PageNode::Page(r) => r.is_leaf(),
378 PageNode::Node(n) => n.cell.borrow().is_leaf,
379 }
380 }
381}
382
383#[derive(Clone, Eq, PartialEq)]
384pub(crate) struct InnerCursor<'tx> {
385 pub(crate) bucket: BucketCell<'tx>,
386 stack: BVec<'tx, ElemRef<'tx>>,
387}
388
389impl<'tx> InnerCursor<'tx> {
390 pub(crate) fn new(cell: BucketCell<'tx>, bump: &'tx Bump) -> Self {
391 cell
392 .tx()
393 .split_r()
394 .stats
395 .as_ref()
396 .unwrap()
397 .inc_cursor_count(1);
398 InnerCursor {
399 bucket: cell,
400 stack: BVec::with_capacity_in(0, bump),
401 }
402 }
403}
404
405impl<'tx> CursorIApi<'tx> for InnerCursor<'tx> {
406 fn api_first(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)> {
407 let (k, v, flags) = self.i_first()?;
408 if (flags & BUCKET_LEAF_FLAG) != 0 {
409 return Some((k, None));
410 }
411 Some((k, Some(v)))
412 }
413
414 fn i_first(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)> {
415 self.stack.clear();
416
417 let root = self.bucket.root();
419 let pn = self.bucket.page_node(root);
420 self.stack.push(ElemRef { pn, index: 0 });
421
422 self.go_to_first_element_on_the_stack();
423
424 if self.stack.last().unwrap().count() == 0 {
427 self.i_next();
428 }
429
430 self.key_value()
431 }
432
433 fn api_next(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)> {
434 let (k, v, flags) = self.i_next()?;
435 if flags & BUCKET_LEAF_FLAG != 0 {
436 Some((k, None))
437 } else {
438 Some((k, Some(v)))
439 }
440 }
441
442 fn i_next(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)> {
445 loop {
446 let mut stack_exhausted = true;
449 let mut new_stack_depth = 0;
450 for (depth, elem) in self.stack.iter_mut().enumerate().rev() {
451 new_stack_depth = depth + 1;
452 if elem.index < elem.count() as i32 - 1 {
453 elem.index += 1;
454 stack_exhausted = false;
455 break;
456 }
457 }
458
459 if stack_exhausted {
462 return None;
463 }
464
465 self.stack.truncate(new_stack_depth);
468 self.go_to_first_element_on_the_stack();
469
470 if let Some(elem) = self.stack.last() {
473 if elem.count() == 0 {
474 continue;
475 }
476 }
477
478 return self.key_value();
479 }
480 }
481
482 fn api_prev(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)> {
483 let (k, v, flags) = self.i_prev()?;
484 if flags & BUCKET_LEAF_FLAG != 0 {
485 Some((k, None))
486 } else {
487 Some((k, Some(v)))
488 }
489 }
490
491 fn i_prev(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)> {
494 let mut new_stack_depth = 0;
497 let mut stack_exhausted = true;
498 for (depth, elem) in self.stack.iter_mut().enumerate().rev() {
499 new_stack_depth = depth + 1;
500 if elem.index > 0 {
501 elem.index -= 1;
502 stack_exhausted = false;
503 break;
504 }
505 if new_stack_depth == 1 {
511 self.i_first();
512 return None;
513 }
514 }
515 if stack_exhausted {
516 self.stack.truncate(0);
517 } else {
518 self.stack.truncate(new_stack_depth);
519 }
520
521 if self.stack.is_empty() {
523 return None;
524 }
525
526 self.i_last();
528
529 self.key_value()
530 }
531
532 fn api_last(&mut self) -> Option<(&'tx [u8], Option<&'tx [u8]>)> {
533 self.stack.truncate(0);
534 let root = self.bucket.root();
535 let pn = self.bucket.page_node(root);
536 let mut elem_ref = ElemRef { pn, index: 0 };
537 elem_ref.index = elem_ref.count() as i32 - 1;
538 self.stack.push(elem_ref);
539 self.i_last();
540
541 while self.stack.len() > 1 && self.stack.last().unwrap().count() == 0 {
542 self.i_prev();
543 }
544
545 if self.stack.is_empty() {
546 return None;
547 }
548
549 let (k, v, flags) = self.key_value()?;
550
551 if flags & BUCKET_LEAF_FLAG != 0 {
552 Some((k, None))
553 } else {
554 Some((k, Some(v)))
555 }
556 }
557
558 fn i_last(&mut self) -> Option<(&'tx [u8], &'tx [u8], u32)> {
561 loop {
562 if let Some(elem) = self.stack.last() {
564 if elem.is_leaf() {
565 break;
566 }
567
568 let pgid = match &elem.pn {
570 PageNode::Page(page) => {
571 let branch_page = MappedBranchPage::coerce_ref(page).unwrap();
572 branch_page.get_elem(elem.index as u16).unwrap().pgid()
573 }
574 PageNode::Node(node) => node.cell.borrow().inodes[elem.index as usize].pgid(),
575 };
576
577 let pn = self.bucket.page_node(pgid);
578 let mut next_elem = ElemRef { pn, index: 0 };
579 next_elem.index = next_elem.count() as i32 - 1;
580 self.stack.push(next_elem);
581 }
582 }
583 self.key_value()
584 }
585
586 fn key_value(&self) -> Option<(&'tx [u8], &'tx [u8], u32)> {
587 let elem_ref = self.stack.last().unwrap();
588 let pn_count = elem_ref.count();
589
590 if pn_count == 0 || elem_ref.index as u32 > pn_count {
592 return None;
593 }
594
595 match &elem_ref.pn {
596 PageNode::Page(r) => {
598 let l = MappedLeafPage::coerce_ref(r).unwrap();
599 l.get_elem(elem_ref.index as u16)
600 .map(|inode| (inode.key(), inode.value(), inode.flags()))
601 }
602 PageNode::Node(n) => {
604 let ref_node = n.cell.borrow();
605 ref_node
606 .inodes
607 .get(elem_ref.index as usize)
608 .map(|inode| (inode.key(), inode.value(), inode.flags()))
609 }
610 }
611 }
612
613 fn api_seek(&mut self, seek: &[u8]) -> Option<(&'tx [u8], Option<&'tx [u8]>)> {
614 let mut vals = self.i_seek(seek);
615
616 if let Some(elem_ref) = self.stack.last() {
617 if elem_ref.index >= elem_ref.count() as i32 {
618 vals = self.i_next();
619 }
620 }
621
622 let (k, v, flags) = vals?;
623 if flags & BUCKET_LEAF_FLAG != 0 {
624 Some((k, None))
625 } else {
626 Some((k, Some(v)))
627 }
628 }
629
630 fn i_seek(&mut self, seek: &[u8]) -> Option<(&'tx [u8], &'tx [u8], u32)> {
631 self.stack.truncate(0);
632 let root = self.bucket.root();
633 self.search(seek, root);
634
635 self.key_value()
636 }
637
638 fn go_to_first_element_on_the_stack(&mut self) {
640 loop {
641 let _slice = self.stack.as_slice();
642 let pgid = {
643 let r = self.stack.last().unwrap();
645 if r.is_leaf() {
646 break;
647 }
648
649 match r.pn {
651 PageNode::Page(page) => {
652 let branch_page = MappedBranchPage::coerce_ref(&page).unwrap();
653 let elem = branch_page.get_elem(r.index as u16).unwrap();
654 elem.pgid()
655 }
656 PageNode::Node(node) => {
657 let node_borrow = node.cell.borrow();
658 node_borrow.inodes[r.index as usize].pgid()
659 }
660 }
661 };
662 let pn = self.bucket.page_node(pgid);
663 self.stack.push(ElemRef { pn, index: 0 })
664 }
665 }
666
667 fn search(&mut self, key: &[u8], pgid: PgId) {
669 let pn = self.bucket.page_node(pgid);
670
671 if let PageNode::Page(page) = &pn {
672 if !page.is_leaf() && !page.is_branch() {
673 panic!("invalid page type: {}, {:X}", page.id, page.flags);
674 }
675 }
676
677 let elem = ElemRef { pn, index: 0 };
678
679 let elem_is_leaf = elem.is_leaf();
681
682 self.stack.push(elem);
683
684 if elem_is_leaf {
685 self.search_inodes(key);
686 return;
687 }
688
689 match &pn {
690 PageNode::Page(page) => self.search_page(key, page),
691 PageNode::Node(node) => self.search_node(key, *node),
692 }
693 }
694
695 fn search_inodes(&mut self, key: &[u8]) {
697 if let Some(elem) = self.stack.last_mut() {
698 let index = match &elem.pn {
699 PageNode::Page(page) => {
701 let leaf_page = MappedLeafPage::coerce_ref(page).unwrap();
702 leaf_page
703 .elements()
704 .partition_point(|elem| unsafe { elem.key(leaf_page.page_ptr().cast_const()) } < key)
705 }
706 PageNode::Node(node) => node
708 .cell
709 .borrow()
710 .inodes
711 .partition_point(|inode| inode.key() < key),
712 };
713 elem.index = index as i32;
714 }
715 }
716
717 fn search_node(&mut self, key: &[u8], node: NodeRwCell<'tx>) {
718 let (index, pgid) = {
719 let w = node.cell.borrow();
720
721 let r = w.inodes.binary_search_by_key(&key, |inode| inode.key());
722 let index = r.unwrap_or_else(|index| if index > 0 { index - 1 } else { index });
723 (index as u32, w.inodes[index].pgid())
724 };
725
726 if let Some(elem) = self.stack.last_mut() {
727 elem.index = index as i32;
728 }
729
730 self.search(key, pgid)
732 }
733
734 fn search_page(&mut self, key: &[u8], page: &RefPage) {
735 let branch_page = MappedBranchPage::coerce_ref(page).unwrap();
736 let elements = branch_page.elements();
737 debug_assert_ne!(0, elements.len());
738 let r = branch_page
739 .elements()
740 .binary_search_by_key(&key, |elem| unsafe {
741 elem.key(branch_page.page_ptr().cast_const())
742 });
743 let index = r.unwrap_or_else(|index| if index > 0 { index - 1 } else { index });
744
745 if let Some(elem) = self.stack.last_mut() {
746 elem.index = index as i32;
747 }
748 let pgid = branch_page.elements()[index].pgid();
749
750 self.search(key, pgid)
752 }
753}
754
755impl<'tx> CursorRwIApi<'tx> for InnerCursor<'tx> {
756 fn node(&mut self) -> NodeRwCell<'tx> {
757 assert!(
758 !self.stack.is_empty(),
759 "accessing a node with a zero-length cursor stack"
760 );
761
762 if let Some(elem_ref) = self.stack.last() {
764 if let PageNode::Node(node) = elem_ref.pn {
765 if node.cell.borrow().is_leaf {
766 return node;
767 }
768 }
769 }
770
771 let mut n = {
773 match &self.stack.first().unwrap().pn {
774 PageNode::Page(page) => self.bucket.node(page.id, None),
775 PageNode::Node(node) => *node,
776 }
777 };
778 let _stack = &self.stack[0..self.stack.len() - 1];
779 for elem in &self.stack[0..self.stack.len() - 1] {
780 assert!(!n.cell.borrow().is_leaf, "expected branch node");
781 n = n.child_at(elem.index as u32);
782 }
783 assert!(n.cell.borrow().is_leaf, "expected leaf node");
784 n
785 }
786
787 fn api_delete(&mut self) -> crate::Result<()> {
788 let (k, _, flags) = self.key_value().unwrap();
789 if flags & BUCKET_LEAF_FLAG != 0 {
790 return Err(IncompatibleValue);
791 }
792 self.node().del(k);
793 Ok(())
794 }
795}
796
797#[cfg(test)]
798mod tests {
799 use crate::test_support::{quick_check, DummyVec, TestDb};
800 use crate::{
801 BucketApi, BucketImpl, BucketRwApi, BucketRwImpl, CursorApi, CursorRwApi, DbApi, DbRwAPI,
802 Error, TxApi, TxRwApi, TxRwRefApi,
803 };
804
805 #[test]
806 fn test_cursor_repeat_operations() -> crate::Result<()> {
807 let tests: Vec<(&'static str, fn(&BucketImpl) -> crate::Result<()>)> = vec![
808 (
809 "Repeat NextPrevNext",
810 test_repeat_cursor_operations_next_prev_next,
811 ),
812 (
813 "Repeat PrevNextPrev",
814 test_repeat_cursor_operations_prev_next_prev,
815 ),
816 ];
817 for (_name, f) in tests {
818 let mut db = TestDb::new()?;
819 let bucket_name = "data";
820 db.update(|mut tx| {
821 let mut b = tx.create_bucket_if_not_exists(bucket_name)?;
822 test_cursor_repeat_operations_prepare_data(&mut b)
823 })?;
824
825 db.view(|tx| {
826 let b = tx.bucket(bucket_name).unwrap();
827 f(&b)
828 })?;
829 }
830 Ok(())
831 }
832
833 fn test_cursor_repeat_operations_prepare_data(b: &mut BucketRwImpl) -> crate::Result<()> {
834 for i in 0..1000 {
835 let k = format!("{:05}", i);
836 b.put(&k, &k)?;
837 }
838 Ok(())
839 }
840
841 fn test_repeat_cursor_operations_next_prev_next(b: &BucketImpl) -> crate::Result<()> {
842 let mut c = b.cursor();
843 c.first();
844 let start_key = format!("{:05}", 2);
845 let (returned_key, _) = c.seek(&start_key).unwrap();
846 assert_eq!(start_key.as_bytes(), returned_key);
847
848 for i in 3..1000 {
850 let expected_key = format!("{:05}", i);
851 let (actual_key, _) = c.next().unwrap();
852 assert_eq!(expected_key.as_bytes(), actual_key);
853 }
854
855 for _ in 0..10 {
857 assert_eq!(None, c.next());
858 }
859
860 for i in (0..999).rev() {
862 let expected_key = format!("{:05}", i);
863 let (actual_key, _) = c.prev().unwrap();
864 assert_eq!(expected_key.as_bytes(), actual_key);
865 }
866
867 for _ in 0..10 {
869 assert_eq!(None, c.prev());
870 }
871
872 for i in 1..1000 {
874 let expected_key = format!("{:05}", i);
875 let (actual_key, _) = c.next().unwrap();
876 assert_eq!(expected_key.as_bytes(), actual_key);
877 }
878
879 Ok(())
880 }
881
882 fn test_repeat_cursor_operations_prev_next_prev(b: &BucketImpl) -> crate::Result<()> {
883 let mut c = b.cursor();
884 let start_key = format!("{:05}", 998);
885 let (returned_key, _) = c.seek(&start_key).unwrap();
886 assert_eq!(start_key.as_bytes(), returned_key);
887
888 for i in (0..998).rev() {
890 let expected_key = format!("{:05}", i);
891 let (actual_key, _) = c.prev().unwrap();
892 assert_eq!(expected_key.as_bytes(), actual_key);
893 }
894
895 for _ in 0..10 {
897 assert_eq!(None, c.prev());
898 }
899
900 for i in 1..1000 {
902 let expected_key = format!("{:05}", i);
903 let (actual_key, _) = c.next().unwrap();
904 assert_eq!(expected_key.as_bytes(), actual_key);
905 }
906
907 for _ in 0..10 {
909 assert_eq!(None, c.next());
910 }
911
912 for i in (0..999).rev() {
914 let expected_key = format!("{:05}", i);
915 let (actual_key, _) = c.prev().unwrap();
916 assert_eq!(expected_key.as_bytes(), actual_key);
917 }
918
919 Ok(())
920 }
921
922 #[test]
924 fn test_cursor_seek() -> crate::Result<()> {
925 let mut db = TestDb::new()?;
926 db.update(|mut tx| {
927 let mut b = tx.create_bucket(b"widgets")?;
928 b.put(b"foo", b"0001")?;
929 b.put(b"bar", b"0002")?;
930 b.put(b"baz", b"0003")?;
931 let _ = b.create_bucket(b"bkt")?;
932 Ok(())
933 })?;
934 db.view(|tx| {
935 let b = tx.bucket(b"widgets").unwrap();
936 let mut c = b.cursor();
937 assert_eq!(
939 (b"bar".as_slice(), Some(b"0002".as_slice())),
940 c.seek(b"bar").unwrap()
941 );
942 assert_eq!(
944 (b"baz".as_slice(), Some(b"0003".as_slice())),
945 c.seek(b"bas").unwrap()
946 );
947 assert_eq!(
949 (b"bar".as_slice(), Some(b"0002".as_slice())),
950 c.seek(b"").unwrap()
951 );
952 assert_eq!(None, c.seek(b"zzz"));
954 assert_eq!((b"bkt".as_slice(), None), c.seek(b"bkt").unwrap());
956 Ok(())
957 })
958 }
959
960 #[test]
961 #[cfg(not(miri))]
962 fn test_cursor_delete() -> crate::Result<()> {
963 let mut db = TestDb::new()?;
964 let count = 1000u64;
965 let value = [0u8; 100];
966 db.update(|mut tx| {
967 let mut b = tx.create_bucket(b"widgets")?;
968 for i in 0..count {
969 let be_i = i.to_be_bytes();
970 b.put(be_i, value)?;
971 }
972 let _ = b.create_bucket(b"sub")?;
973 Ok(())
974 })?;
975 db.must_check();
976 db.update(|mut tx| {
977 let b = tx.bucket_mut(b"widgets").unwrap();
978 let mut c = b.cursor_mut();
979 let bound = (count / 2).to_be_bytes();
980 let (mut key, _) = c.first().unwrap();
981 while key < bound.as_slice() {
982 c.delete()?;
983 key = c.next().unwrap().0;
984 }
985 c.seek(b"sub");
986 assert_eq!(Err(Error::IncompatibleValue), c.delete());
987 Ok(())
988 })?;
989 db.must_check();
990 db.view(|tx| {
991 let b = tx.bucket(b"widgets").unwrap();
992 let stats = b.stats();
993 assert_eq!((count / 2) + 1, stats.key_n as u64);
994 Ok(())
995 })?;
996 Ok(())
997 }
998
999 #[test]
1000 #[cfg(not(miri))]
1001 fn test_cursor_seek_large() -> crate::Result<()> {
1002 let mut db = TestDb::new()?;
1003 let count = 1000u64;
1004 let value = [0u8; 100];
1005 db.update(|mut tx| {
1006 let mut b = tx.create_bucket(b"widgets")?;
1007 for i in (0..count).step_by(100) {
1008 for j in (i..i + 100).step_by(2) {
1009 let k = j.to_be_bytes();
1010 b.put(k, value)?;
1011 }
1012 }
1013 Ok(())
1014 })?;
1015 db.view(|tx| {
1016 let b = tx.bucket(b"widgets").unwrap();
1017 let mut c = b.cursor();
1018 for i in 0..count {
1019 let seek = i.to_be_bytes();
1020 let sought = c.seek(seek);
1021
1022 if i == count - 1 {
1023 assert!(sought.is_none(), "expected None");
1024 continue;
1025 }
1026 let k = sought.unwrap().0;
1027 let num = u64::from_be_bytes(k.try_into().unwrap());
1028 if i % 2 == 0 {
1029 assert_eq!(num, i, "unexpected num: {}", num)
1030 } else {
1031 assert_eq!(num, i + 1, "unexpected num: {}", num)
1032 }
1033 }
1034 Ok(())
1035 })?;
1036 Ok(())
1037 }
1038
1039 #[test]
1040 fn test_cursor_empty_bucket() -> crate::Result<()> {
1041 let mut db = TestDb::new()?;
1042 db.update(|mut tx| {
1043 let _ = tx.create_bucket(b"widgets")?;
1044 Ok(())
1045 })?;
1046 db.view(|tx| {
1047 let b = tx.bucket(b"widgets").unwrap();
1048 let mut c = b.cursor();
1049 let kv = c.first();
1050 assert_eq!(None, kv, "unexpected kv: {:?}", kv);
1051 Ok(())
1052 })?;
1053 Ok(())
1054 }
1055
1056 #[test]
1057 fn test_cursor_empty_bucket_reverse() -> crate::Result<()> {
1058 let mut db = TestDb::new()?;
1059 db.update(|mut tx| {
1060 let _ = tx.create_bucket(b"widgets")?;
1061 Ok(())
1062 })?;
1063 db.view(|tx| {
1064 let b = tx.bucket(b"widgets").unwrap();
1065 let mut c = b.cursor();
1066 let kv = c.last();
1067 assert_eq!(None, kv, "unexpected kv: {:?}", kv);
1068 Ok(())
1069 })?;
1070 Ok(())
1071 }
1072
1073 #[test]
1074 fn test_cursor_iterate_leaf() -> crate::Result<()> {
1075 let mut db = TestDb::new()?;
1076 db.update(|mut tx| {
1077 let mut b = tx.create_bucket(b"widgets")?;
1078 b.put(b"baz", [])?;
1079 b.put(b"foo", [0])?;
1080 b.put(b"bar", [1])?;
1081 Ok(())
1082 })?;
1083 let tx = db.begin()?;
1084 {
1085 let b = tx.bucket(b"widgets").unwrap();
1086 let mut c = b.cursor();
1087 assert_eq!(Some((b"bar".as_slice(), Some([1].as_slice()))), c.first());
1088 assert_eq!(Some((b"baz".as_slice(), Some([].as_slice()))), c.next());
1089 assert_eq!(Some((b"foo".as_slice(), Some([0].as_slice()))), c.next());
1090 assert_eq!(None, c.next());
1091 assert_eq!(None, c.next());
1092 }
1093 Ok(())
1094 }
1095
1096 #[test]
1097 fn test_cursor_leaf_root_reverse() -> crate::Result<()> {
1098 let mut db = TestDb::new()?;
1099 db.update(|mut tx| {
1100 let mut b = tx.create_bucket(b"widgets")?;
1101 b.put(b"baz", [])?;
1102 b.put(b"foo", [0])?;
1103 b.put(b"bar", [1])?;
1104 Ok(())
1105 })?;
1106 let tx = db.begin()?;
1107 {
1108 let b = tx.bucket(b"widgets").unwrap();
1109 let mut c = b.cursor();
1110 assert_eq!(Some((b"foo".as_slice(), Some([0].as_slice()))), c.last());
1111 assert_eq!(Some((b"baz".as_slice(), Some([].as_slice()))), c.prev());
1112 assert_eq!(Some((b"bar".as_slice(), Some([1].as_slice()))), c.prev());
1113 assert_eq!(None, c.prev());
1114 assert_eq!(None, c.prev());
1115 }
1116 Ok(())
1117 }
1118
1119 #[test]
1120 fn test_cursor_restart() -> crate::Result<()> {
1121 let mut db = TestDb::new()?;
1122 db.update(|mut tx| {
1123 let mut b = tx.create_bucket(b"widgets")?;
1124 b.put("foo", [])?;
1125 b.put("bar", [])?;
1126 Ok(())
1127 })?;
1128 let tx = db.begin()?;
1129 {
1130 let b = tx.bucket(b"widgets").unwrap();
1131 let mut c = b.cursor();
1132 assert_eq!(Some((b"bar".as_slice(), Some([].as_slice()))), c.first());
1133 assert_eq!(Some((b"foo".as_slice(), Some([].as_slice()))), c.next());
1134 assert_eq!(Some((b"bar".as_slice(), Some([].as_slice()))), c.first());
1135 assert_eq!(Some((b"foo".as_slice(), Some([].as_slice()))), c.next());
1136 }
1137 Ok(())
1138 }
1139
1140 #[test]
1141 fn test_cursor_first_empty_pages() -> crate::Result<()> {
1142 let mut db = TestDb::new()?;
1143 db.update(|mut tx| {
1144 let mut b = tx.create_bucket(b"widgets")?;
1145 for i in 1..1000u64 {
1146 b.put(bytemuck::bytes_of(&i), [])?;
1147 }
1148 Ok(())
1149 })?;
1150 db.update(|mut tx| {
1151 let mut b = tx.bucket_mut(b"widgets").unwrap();
1152 for i in 1..600u64 {
1153 b.delete(bytemuck::bytes_of(&i))?;
1154 }
1155 let mut c = b.cursor();
1156 let mut kv = c.first();
1157 let mut n = 0;
1158 while kv.is_some() {
1159 n += 1;
1160 kv = c.next();
1161 }
1162 assert_eq!(400, n, "unexpected key count");
1163 Ok(())
1164 })
1165 }
1166
1167 #[test]
1168 fn test_cursor_last_empty_pages() -> crate::Result<()> {
1169 let mut db = TestDb::new()?;
1170 db.update(|mut tx| {
1171 let mut b = tx.create_bucket(b"widgets")?;
1172 for i in 0..1000u64 {
1173 b.put(bytemuck::bytes_of(&i), [])?;
1174 }
1175 Ok(())
1176 })?;
1177 db.update(|mut tx| {
1178 let mut b = tx.bucket_mut(b"widgets").unwrap();
1179 for i in 200..1000u64 {
1180 b.delete(bytemuck::bytes_of(&i))?;
1181 }
1182 let mut c = b.cursor();
1183 let mut kv = c.last();
1184 let mut n = 0;
1185 while kv.is_some() {
1186 n += 1;
1187 kv = c.prev();
1188 }
1189 assert_eq!(200, n, "unexpected key count");
1190 Ok(())
1191 })
1192 }
1193
1194 #[test]
1195 fn test_cursor_quick_check() {
1196 quick_check(5, |d: &mut DummyVec| {
1197 let mut db = TestDb::new().expect("error");
1198 let mut tx = db.begin_rw_tx().expect("error");
1199 let mut b = tx.create_bucket("widgets").expect("error");
1200
1201 for entry in &d.values {
1202 b.put(&entry.key, &entry.value).expect("error");
1203 }
1204
1205 tx.commit().expect("error");
1206
1207 d.values.sort_by(|d1, d2| d1.key.cmp(&d2.key));
1208
1209 let tx = db.begin_tx().expect("error");
1210
1211 let b = tx.bucket("widgets").unwrap();
1212 for (entry, (key, value)) in d.values.iter().zip(b.iter_entries()) {
1213 assert_eq!(&entry.key, key, "unexpected key");
1214 assert_eq!(&entry.value, value, "unexpected value");
1215 }
1216
1217 true
1218 });
1219 }
1220
1221 #[test]
1222 fn test_cursor_quick_check_reverse() {
1223 quick_check(5, |d: &mut DummyVec| {
1224 let mut db = TestDb::new().expect("error");
1225 let mut tx = db.begin_rw_tx().expect("error");
1226 let mut b = tx.create_bucket("widgets").expect("error");
1227
1228 for entry in &d.values {
1229 b.put(&entry.key, &entry.value).expect("error");
1230 }
1231
1232 tx.commit().expect("error");
1233
1234 d.values.sort_by(|d1, d2| d1.key.cmp(&d2.key).reverse());
1235
1236 let tx = db.begin_tx().expect("error");
1237
1238 let b = tx.bucket("widgets").unwrap();
1239 for (entry, (key, value)) in d.values.iter().zip(b.iter_entries().rev()) {
1240 assert_eq!(&entry.key, key, "unexpected key");
1241 assert_eq!(&entry.value, value, "unexpected value");
1242 }
1243
1244 true
1245 });
1246 }
1247
1248 #[test]
1249 fn test_cursor_quick_check_buckets_only() -> crate::Result<()> {
1250 let mut expected = vec![b"foo".to_vec(), b"bar".to_vec(), b"baz".to_vec()];
1251 let mut db = TestDb::new()?;
1252 db.update(|mut tx| {
1253 let mut b = tx.create_bucket("widgets")?;
1254 for bucket in &expected {
1255 b.create_bucket(bucket)?;
1256 }
1257 Ok(())
1258 })?;
1259 expected.sort();
1260 db.view(|tx| {
1261 let b = tx.bucket("widgets").unwrap();
1262 let actual: Vec<Vec<u8>> = b.iter_buckets().map(|(key, _)| key.to_vec()).collect();
1263 assert_eq!(expected.as_ref(), actual);
1264 Ok(())
1265 })?;
1266 Ok(())
1267 }
1268
1269 #[test]
1270 fn test_cursor_quick_check_buckets_only_reverse() -> crate::Result<()> {
1271 let mut expected = vec![b"foo".to_vec(), b"bar".to_vec(), b"baz".to_vec()];
1272 let mut db = TestDb::new()?;
1273 db.update(|mut tx| {
1274 let mut b = tx.create_bucket("widgets")?;
1275 for bucket in &expected {
1276 b.create_bucket(bucket)?;
1277 }
1278 Ok(())
1279 })?;
1280 expected.sort_by(|a, b| b.cmp(a));
1281 db.view(|tx| {
1282 let b = tx.bucket("widgets").unwrap();
1283 let actual: Vec<Vec<u8>> = b
1284 .iter_buckets()
1285 .rev()
1286 .map(|(key, _)| key.to_vec())
1287 .collect();
1288 assert_eq!(expected.as_ref(), actual);
1289 Ok(())
1290 })?;
1291 Ok(())
1292 }
1293}