cdb64/lib.rs
1//! # cdb64
2//!
3//! `cdb64` is a Rust implementation of D. J. Bernstein's cdb (constant database) format,
4//! specifically designed to handle large database files efficiently using 64-bit hash values and offsets.
5//!
6//! This library provides `CdbWriter` for creating cdb files and `Cdb` for reading existing cdb files.
7//! It also includes `CdbIterator` for iterating over all key-value pairs within a database.
8//!
9//! ## Features
10//!
11//! - CDB file creation (`CdbWriter`)
12//! - CDB file reading and key lookups (`Cdb`)
13//! - Database iteration (`CdbIterator`)
14//! - Support for custom hash functions (defaults to CDB hash)
15//!
16//! ## Usage Examples
17//!
18//! ### Creating and Reading a CDB File
19//!
20//! ```rust
21//! use cdb64::{CdbWriter, Cdb, Error, CdbHash};
22//! use tempfile::NamedTempFile;
23//! use std::fs::File;
24//!
25//! fn main() -> Result<(), Error> {
26//! let temp_file = NamedTempFile::new().expect("Failed to create temp file");
27//! let path = temp_file.path();
28//!
29//! // Create a CDB file
30//! let mut writer = CdbWriter::<File, CdbHash>::create(path)?;
31//! writer.put(b"hello", b"world")?;
32//! writer.put(b"rust", b"is awesome")?;
33//! writer.finalize()?; // After finalize, writer can still be used (but put is blocked by is_finalized)
34//!
35//! // Open the CDB file
36//! let cdb = Cdb::<File, CdbHash>::open(path)?;
37//!
38//! // Retrieve a value by key
39//! if let Some(value) = cdb.get(b"hello")? {
40//! println!("Found value: {}", String::from_utf8_lossy(&value));
41//! }
42//!
43//! // Search for a non-existent key
44//! assert!(cdb.get(b"nonexistent")?.is_none());
45//!
46//! Ok(())
47//! }
48//! ```
49//!
50//! ### Using the Iterator
51//!
52//! ```rust
53//! use cdb64::{CdbWriter, Cdb, CdbIterator, Error, CdbHash};
54//! use tempfile::NamedTempFile;
55//! use std::collections::HashMap;
56//! use std::fs::File;
57//!
58//! fn main() -> Result<(), Error> {
59//! let temp_file = NamedTempFile::new().expect("Failed to create temp file");
60//! let path = temp_file.path();
61//!
62//! let mut data = HashMap::new();
63//! data.insert(b"key1".to_vec(), b"value1".to_vec());
64//! data.insert(b"key2".to_vec(), b"value2".to_vec());
65//!
66//! let mut writer = CdbWriter::<File, CdbHash>::create(path)?;
67//! for (k, v) in &data {
68//! writer.put(k, v)?;
69//! }
70//! writer.finalize()?;
71//!
72//! let cdb: Cdb<_, CdbHash> = Cdb::open(path)?;
73//! let iter = cdb.iter();
74//!
75//! let mut retrieved_count = 0;
76//! for result in iter {
77//! let (key, value) = result?;
78//! println!("Key: {}, Value: {}",
79//! String::from_utf8_lossy(&key),
80//! String::from_utf8_lossy(&value)
81//! );
82//! assert_eq!(data.get(&key).unwrap(), &value);
83//! retrieved_count += 1;
84//! }
85//! assert_eq!(retrieved_count, data.len());
86//!
87//! Ok(())
88//! }
89//! ```
90
91mod cdb;
92mod hash;
93mod iterator;
94mod util;
95mod writer;
96
97// re-exports
98pub use cdb::Cdb;
99pub use hash::CdbHash;
100pub use iterator::CdbIterator;
101pub use util::ReaderAt;
102pub use writer::CdbWriter;
103
104/// Errors that can occur when working with CDB databases.
105#[derive(Debug, thiserror::Error)]
106pub enum Error {
107 /// An I/O error occurred during file operations.
108 ///
109 /// This can happen during:
110 /// - File opening, reading, or writing
111 /// - Memory mapping (when mmap feature is enabled)
112 /// - Data serialization or deserialization
113 #[error("I/O error: {0}")]
114 Io(#[from] std::io::Error),
115
116 /// Indicates an attempt to operate on a writer that has already been finalized.
117 ///
118 /// Once `CdbWriter::finalize()` is called, no further `put()` operations are allowed.
119 /// This error is returned if you try to call `put()` after finalization.
120 ///
121 /// # Example
122 ///
123 /// ```
124 /// use cdb64::{CdbWriter, CdbHash, Error};
125 /// use std::io::Cursor;
126 ///
127 /// let mut writer = CdbWriter::<_, CdbHash>::new(Cursor::new(Vec::new())).unwrap();
128 /// writer.finalize().unwrap();
129 ///
130 /// // This will fail with WriterFinalized error
131 /// match writer.put(b"key", b"value") {
132 /// Err(Error::WriterFinalized) => println!("Expected error!"),
133 /// _ => panic!("Should have failed"),
134 /// }
135 /// ```
136 #[error("Attempted to operate on a finalized writer")]
137 WriterFinalized,
138
139 /// Indicates an attempt to use a writer that has not been finalized yet when finalization is required.
140 ///
141 /// This error is returned by `CdbWriter::into_inner()` if `finalize()` has not been called.
142 /// You must call `finalize()` to complete the database structure before consuming the writer.
143 ///
144 /// # Example
145 ///
146 /// ```
147 /// use cdb64::{CdbWriter, CdbHash, Error};
148 /// use std::io::Cursor;
149 ///
150 /// let mut writer = CdbWriter::<_, CdbHash>::new(Cursor::new(Vec::new())).unwrap();
151 /// writer.put(b"key", b"value").unwrap();
152 ///
153 /// // This will fail with WriterNotFinalized error
154 /// match writer.into_inner() {
155 /// Err(Error::WriterNotFinalized) => println!("Expected error!"),
156 /// _ => panic!("Should have failed"),
157 /// }
158 /// ```
159 #[error("Writer has not been finalized yet")]
160 WriterNotFinalized,
161}