1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
//! # Walrus ðŸ¦
//!
//! A high-performance Write-Ahead Log (WAL) implementation in Rust designed for concurrent
//! workloads with topic-based organization, configurable consistency models, and dual storage backends.
//!
//! ## Features
//!
//! - **High Performance**: Optimized for concurrent writes and reads
//! - **Topic-based Organization**: Separate read/write streams per topic
//! - **Configurable Consistency**: Choose between strict and relaxed consistency models
//! - **Batched I/O**: Atomic batch append and read APIs (uses io_uring on Linux with FD backend)
//! - **Dual Storage Backends**: FD backend with pread/pwrite (default) or mmap backend
//! - **Persistent Read Offsets**: Read positions survive process restarts
//! - **Namespace Isolation**: Separate WAL instances with per-key directories
//!
//! ## Quick Start
//!
//! ```rust,no_run
//! use walrus_rust::{Walrus, ReadConsistency};
//!
//! # fn main() -> std::io::Result<()> {
//! // Create a new WAL instance
//! let wal = Walrus::new()?;
//!
//! // Write data to a topic
//! wal.append_for_topic("my-topic", b"Hello, Walrus!")?;
//!
//! // Read data from the topic (checkpoint=true consumes the entry)
//! if let Some(entry) = wal.read_next("my-topic", true)? {
//! println!("Read: {:?}", String::from_utf8_lossy(&entry.data));
//! }
//!
//! // Peek at the next entry without consuming it (checkpoint=false)
//! if let Some(entry) = wal.read_next("my-topic", false)? {
//! println!("Peeking: {:?}", String::from_utf8_lossy(&entry.data));
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Batch Operations
//!
//! Walrus supports efficient batch writes and reads. On Linux with the FD backend (default),
//! batch operations automatically use io_uring for parallel I/O submission. On other platforms
//! or with the mmap backend, batches fall back to sequential operations.
//!
//! **Limits:**
//! - Maximum 2,000 entries per batch
//! - Maximum ~10GB total payload per batch
//!
//! ```rust,no_run
//! use walrus_rust::Walrus;
//!
//! # fn main() -> std::io::Result<()> {
//! let wal = Walrus::new()?;
//!
//! // Atomic batch write (all-or-nothing)
//! let batch = vec![
//! b"entry 1".as_slice(),
//! b"entry 2".as_slice(),
//! b"entry 3".as_slice(),
//! ];
//! wal.batch_append_for_topic("events", &batch)?;
//!
//! // Batch read with byte limit (returns at least 1 entry if available)
//! let max_bytes = 1024 * 1024; // 1MB
//! let entries = wal.batch_read_for_topic("events", max_bytes, true)?;
//! for entry in entries {
//! println!("Read: {} bytes", entry.data.len());
//! }
//! # Ok(())
//! # }
//! ```
//!
//! ## Consistency Models
//!
//! Control the trade-off between durability and performance:
//!
//! ```rust,no_run
//! use walrus_rust::{Walrus, ReadConsistency, FsyncSchedule};
//!
//! # fn main() -> std::io::Result<()> {
//! // Strict consistency - every read checkpoint is persisted immediately
//! let wal = Walrus::with_consistency(ReadConsistency::StrictlyAtOnce)?;
//!
//! // At-least-once delivery - persist every N reads (higher throughput)
//! // This allows replaying up to N entries after a crash
//! let wal = Walrus::with_consistency(
//! ReadConsistency::AtLeastOnce { persist_every: 1000 }
//! )?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Fsync Scheduling
//!
//! Configure when data is flushed to disk:
//!
//! ```rust,no_run
//! use walrus_rust::{Walrus, ReadConsistency, FsyncSchedule};
//!
//! # fn main() -> std::io::Result<()> {
//! // Fsync every 500ms (default is 200ms)
//! let wal = Walrus::with_consistency_and_schedule(
//! ReadConsistency::StrictlyAtOnce,
//! FsyncSchedule::Milliseconds(500)
//! )?;
//!
//! // Fsync after every single write (maximum durability, lower throughput)
//! let wal = Walrus::with_consistency_and_schedule(
//! ReadConsistency::StrictlyAtOnce,
//! FsyncSchedule::SyncEach
//! )?;
//!
//! // Never fsync (maximum throughput, no durability guarantees)
//! let wal = Walrus::with_consistency_and_schedule(
//! ReadConsistency::StrictlyAtOnce,
//! FsyncSchedule::NoFsync
//! )?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Namespace Isolation
//!
//! Create isolated WAL instances with separate storage directories:
//!
//! ```rust,no_run
//! use walrus_rust::{Walrus, ReadConsistency, FsyncSchedule};
//!
//! # fn main() -> std::io::Result<()> {
//! // Create a namespaced WAL (stored in wal_files/<sanitized-key>/)
//! let wal1 = Walrus::new_for_key("tenant-123")?;
//! let wal2 = Walrus::new_for_key("tenant-456")?;
//!
//! // With custom consistency
//! let wal = Walrus::with_consistency_for_key(
//! "my-app",
//! ReadConsistency::AtLeastOnce { persist_every: 100 }
//! )?;
//!
//! // With full configuration
//! let wal = Walrus::with_consistency_and_schedule_for_key(
//! "my-app",
//! ReadConsistency::AtLeastOnce { persist_every: 1000 },
//! FsyncSchedule::Milliseconds(500)
//! )?;
//! # Ok(())
//! # }
//! ```
//!
//! ## Storage Backends
//!
//! Walrus supports two storage backends that can be selected at runtime:
//!
//! ### FD Backend (File Descriptor) - Default
//!
//! Uses file descriptors with `pread`/`pwrite` syscalls for I/O operations. This is the
//! default backend and requires Unix-specific APIs.
//!
//! **Batch Operations on Linux:**
//! - When running on Linux, batch operations (`batch_append_for_topic` and `batch_read_for_topic`)
//! automatically use io_uring for high-performance parallel I/O submission
//! - Regular single-entry operations use standard `pread`/`pwrite` syscalls
//!
//! **O_SYNC Mode:**
//! - When `FsyncSchedule::SyncEach` is configured, files are opened with the `O_SYNC` flag,
//! making every write synchronous
//!
//! - **Works on**: Unix systems (Linux, macOS, BSD)
//! - **Best for**: Batch operations on Linux (io_uring), general-purpose workloads
//! - **Default**: Enabled
//!
//! ### Mmap Backend (Memory-Mapped Files)
//!
//! Uses memory-mapped files for direct memory access. Batch operations fall back to
//! sequential reads/writes without io_uring acceleration.
//!
//! - **Works on**: All platforms
//! - **Best for**: Windows, or when FD backend is incompatible
//! - **Default**: Disabled (use `disable_fd_backend()` to enable)
//!
//! ### Selecting a Backend
//!
//! ```rust,no_run
//! use walrus_rust::{enable_fd_backend, disable_fd_backend};
//!
//! // Use FD backend (default - uses io_uring for batches on Linux)
//! enable_fd_backend();
//!
//! // Use mmap backend (no io_uring, sequential batch operations)
//! disable_fd_backend();
//! ```
//!
//! **Important**: Backend selection must be done before creating any `Walrus` instances.
//!
//! ## Environment Variables
//!
//! - `WALRUS_DATA_DIR`: Change storage location (default: `./wal_files`)
//! - `WALRUS_INSTANCE_KEY`: Default namespace for all instances
//! - `WALRUS_QUIET=1`: Suppress debug output
//!
//! ```bash
//! # Example: Use a custom data directory
//! export WALRUS_DATA_DIR=/var/lib/myapp/wal
//!
//! # Example: Set default namespace
//! export WALRUS_INSTANCE_KEY=production
//!
//! # Example: Quiet mode
//! export WALRUS_QUIET=1
//! ```
//!
//! ## Performance Characteristics
//!
//! - **Block size**: 10MB per block
//! - **Batch limits**: Up to 2,000 entries or ~10GB payload per batch
//! - **Default fsync interval**: 200ms
//! - **File organization**: 100 blocks per file (1GB files)
//!
//! ## Types
//!
//! ```rust
//! # use walrus_rust::Entry;
//! // Entry returned by read operations
//! pub struct Entry {
//! pub data: Vec<u8>,
//! }
//! ```
//!
//! ## API Reference
//!
//! ### Constructors
//!
//! - [`Walrus::new()`]: Default constructor (StrictlyAtOnce, 200ms fsync)
//! - [`Walrus::with_consistency()`]: Set read consistency model
//! - [`Walrus::with_consistency_and_schedule()`]: Set consistency and fsync policy
//! - [`Walrus::new_for_key()`]: Create namespaced instance
//! - [`Walrus::with_consistency_for_key()`]: Namespaced with consistency
//! - [`Walrus::with_consistency_and_schedule_for_key()`]: Full namespaced configuration
//!
//! ### Write Operations
//!
//! - [`Walrus::append_for_topic()`]: Append single entry to topic
//! - [`Walrus::batch_append_for_topic()`]: Atomic batch write (up to 2,000 entries)
//!
//! ### Read Operations
//!
//! - [`Walrus::read_next()`]: Read next entry (checkpoint=true consumes, false peeks)
//! - [`Walrus::batch_read_for_topic()`]: Read multiple entries up to byte limit
pub use ;