|
7 | 7 | //! - [Advanced Multithreaded Access of Entries](#advanced-multithreaded-access-of-entries) |
8 | 8 | //! - [Use Custom Key Comparator](#use-custom-key-comparator) |
9 | 9 | //! - [Use Custom Dupsort Comparator](#use-custom-dupsort-comparator) |
| 10 | +//! - [Use Bytes as Cursor Ranges](#use-bytes-as-cursor-ranges) |
10 | 11 | //! |
11 | 12 | //! # Decode Values on Demand |
12 | 13 | //! |
|
580 | 581 | //! } |
581 | 582 | //! ``` |
582 | 583 | //! |
| 584 | +//! # Use Bytes as Cursor Ranges |
| 585 | +//! |
| 586 | +//! When working with databases that have sorted keys, you might want to iterate over a specific range |
| 587 | +//! of keys starting from a particular key. Heed provides the [`Database::range`] method that accepts |
| 588 | +//! any type implementing [`RangeBounds`]. |
| 589 | +//! |
| 590 | +//! Specifically, if your keys are of type [`Bytes`] and you have a `Vec<u8>` as your starting key |
| 591 | +//! you can use that in in a [`Database::range`] call like this: |
| 592 | +//! |
| 593 | +//! ``` |
| 594 | +//! use std::error::Error; |
| 595 | +//! use std::fs; |
| 596 | +//! use std::path::Path; |
| 597 | +//! |
| 598 | +//! use heed::byteorder::NativeEndian; |
| 599 | +//! use heed::types::*; |
| 600 | +//! use heed::{Database, DatabaseFlags, EnvOpenOptions}; |
| 601 | +//! |
| 602 | +//! struct BytesRange(Vec<u8>); |
| 603 | +//! |
| 604 | +//! impl std::ops::RangeBounds<[u8]> for BytesRange { |
| 605 | +//! fn start_bound(&self) -> std::ops::Bound<&[u8]> { |
| 606 | +//! std::ops::Bound::Included(&self.0) |
| 607 | +//! } |
| 608 | +//! |
| 609 | +//! fn end_bound(&self) -> std::ops::Bound<&[u8]> { |
| 610 | +//! std::ops::Bound::Unbounded |
| 611 | +//! } |
| 612 | +//! } |
| 613 | +//! |
| 614 | +//! fn main() -> Result<(), Box<dyn Error>> { |
| 615 | +//! let path = tempfile::tempdir()?; |
| 616 | +//! |
| 617 | +//! let env = unsafe { |
| 618 | +//! EnvOpenOptions::new() |
| 619 | +//! .map_size(1 << 34) |
| 620 | +//! .max_dbs(8) |
| 621 | +//! .open(&path)? |
| 622 | +//! }; |
| 623 | +//! |
| 624 | +//! let mut wtxn = env.write_txn()?; |
| 625 | +//! |
| 626 | +//! let db = env |
| 627 | +//! .database_options() |
| 628 | +//! .types::<Bytes, U64<NativeEndian>>() |
| 629 | +//! .name("index") |
| 630 | +//! .flags(DatabaseFlags::DUP_SORT | DatabaseFlags::DUP_FIXED) |
| 631 | +//! .create(&mut wtxn)?; |
| 632 | +//! |
| 633 | +//! db.put(&mut wtxn, &vec![1, 2, 3, 3], &55555u64)?; |
| 634 | +//! db.put(&mut wtxn, &vec![1, 2, 3, 4], &66666u64)?; |
| 635 | +//! db.put(&mut wtxn, &vec![1, 2, 3, 5], &77777u64)?; |
| 636 | +//! |
| 637 | +//! wtxn.commit()?; |
| 638 | +//! |
| 639 | +//! let txn = env.read_txn()?; |
| 640 | +//! let key: Vec<u8> = vec![1, 2, 3, 4]; |
| 641 | +//! |
| 642 | +//! for result in db.range(&txn, &BytesRange(key))? { |
| 643 | +//! let (k, v) = result?; |
| 644 | +//! println!("Key: {:?}, Value: {}", k, v); |
| 645 | +//! } |
| 646 | +//! |
| 647 | +//! Ok(()) |
| 648 | +//! } |
| 649 | +//! ``` |
| 650 | +//! |
| 651 | +//! |
583 | 652 |
|
584 | 653 | // To let cargo generate doc links |
585 | 654 | #![allow(unused_imports)] |
|
0 commit comments