1#![doc(
84 html_logo_url = "https://raw.githubusercontent.com/spacejam/sled/master/art/tree_face_anti-transphobia.png"
85)]
86#![deny(
87 missing_docs,
88 future_incompatible,
89 nonstandard_style,
90 rust_2018_idioms,
91 missing_copy_implementations,
92 trivial_casts,
93 trivial_numeric_casts,
94 unsafe_code,
95 unused_qualifications
96)]
97#![deny(
98 clippy::cast_lossless,
100 clippy::cast_possible_truncation,
101 clippy::cast_possible_wrap,
102 clippy::cast_precision_loss,
103 clippy::cast_sign_loss,
104 clippy::checked_conversions,
105 clippy::decimal_literal_representation,
106 clippy::doc_markdown,
107 clippy::empty_enum,
109 clippy::explicit_into_iter_loop,
110 clippy::explicit_iter_loop,
111 clippy::expl_impl_clone_on_copy,
112 clippy::fallible_impl_from,
113 clippy::filter_map,
114 clippy::filter_map_next,
115 clippy::find_map,
116 clippy::float_arithmetic,
117 clippy::get_unwrap,
118 clippy::if_not_else,
119 clippy::inline_always,
121 clippy::invalid_upcast_comparisons,
123 clippy::items_after_statements,
124 clippy::map_entry,
125 clippy::map_flatten,
126 clippy::match_same_arms,
127 clippy::maybe_infinite_iter,
128 clippy::mem_forget,
129 clippy::module_name_repetitions,
132 clippy::multiple_inherent_impl,
133 clippy::mut_mut,
134 clippy::needless_borrow,
135 clippy::needless_continue,
136 clippy::needless_pass_by_value,
137 clippy::non_ascii_literal,
138 clippy::path_buf_push_overwrite,
139 clippy::print_stdout,
140 clippy::pub_enum_variant_names,
141 clippy::redundant_closure_for_method_calls,
142 clippy::shadow_reuse,
143 clippy::shadow_same,
144 clippy::shadow_unrelated,
145 clippy::single_match_else,
146 clippy::string_add,
147 clippy::string_add_assign,
148 clippy::type_repetition_in_bounds,
149 clippy::unicode_not_nfc,
150 clippy::unseparated_literal_suffix,
152 clippy::used_underscore_binding,
153 clippy::wildcard_dependencies,
154 clippy::wrong_pub_self_convention,
156)]
157#![warn(clippy::multiple_crate_versions)]
158#![allow(clippy::mem_replace_with_default)] #![allow(clippy::match_like_matches_macro)] macro_rules! io_fail {
162 ($config:expr, $e:expr) => {
163 #[cfg(feature = "failpoints")]
164 {
165 debug_delay();
166 if fail::is_active($e) {
167 $config.set_global_error(Error::FailPoint);
168 return Err(Error::FailPoint).into();
169 }
170 }
171 };
172}
173
174macro_rules! testing_assert {
175 ($($e:expr),*) => {
176 #[cfg(feature = "lock_free_delays")]
177 assert!($($e),*)
178 };
179}
180
181mod arc;
182mod atomic_shim;
183mod batch;
184mod binary_search;
185mod concurrency_control;
186mod config;
187mod context;
188mod db;
189mod dll;
190mod fastcmp;
191mod fastlock;
192mod histogram;
193mod iter;
194mod ivec;
195mod lazy;
196mod lru;
197mod meta;
198mod metrics;
199mod node;
200mod oneshot;
201mod pagecache;
202mod prefix;
203mod result;
204mod serialization;
205mod stack;
206mod subscriber;
207mod sys_limits;
208pub mod transaction;
209mod tree;
210
211#[cfg(feature = "failpoints")]
213pub mod fail;
214
215#[cfg(feature = "docs")]
216pub mod doc;
217
218#[cfg(any(
219 miri,
220 not(any(
221 windows,
222 target_os = "linux",
223 target_os = "macos",
224 target_os = "dragonfly",
225 target_os = "freebsd",
226 target_os = "openbsd",
227 target_os = "netbsd",
228 ))
229))]
230mod threadpool {
231 use super::{OneShot, Result};
232
233 pub fn spawn<F, R>(work: F) -> Result<OneShot<R>>
235 where
236 F: FnOnce() -> R + Send + 'static,
237 R: Send + 'static,
238 {
239 let (promise_filler, promise) = OneShot::pair();
240 promise_filler.fill((work)());
241 Ok(promise)
242 }
243}
244
245#[cfg(all(
246 not(miri),
247 any(
248 windows,
249 target_os = "linux",
250 target_os = "macos",
251 target_os = "dragonfly",
252 target_os = "freebsd",
253 target_os = "openbsd",
254 target_os = "netbsd",
255 )
256))]
257mod threadpool;
258
259#[cfg(all(
260 not(miri),
261 any(
262 windows,
263 target_os = "linux",
264 target_os = "macos",
265 target_os = "dragonfly",
266 target_os = "freebsd",
267 target_os = "openbsd",
268 target_os = "netbsd",
269 )
270))]
271mod flusher;
272
273#[cfg(feature = "event_log")]
274pub mod event_log;
276
277#[cfg(feature = "measure_allocs")]
278mod measure_allocs;
279
280#[cfg(feature = "measure_allocs")]
281#[global_allocator]
282static ALLOCATOR: measure_allocs::TrackingAllocator =
283 measure_allocs::TrackingAllocator;
284
285const DEFAULT_TREE_ID: &[u8] = b"__sled__default";
286
287#[doc(hidden)]
289pub use {
290 self::{
291 config::RunningConfig,
292 lazy::Lazy,
293 pagecache::{
294 constants::{
295 MAX_MSG_HEADER_LEN, MAX_SPACE_AMPLIFICATION,
296 MINIMUM_ITEMS_PER_SEGMENT, SEG_HEADER_LEN,
297 },
298 BatchManifest, DiskPtr, Log, LogKind, LogOffset, LogRead, Lsn,
299 PageCache, PageId,
300 },
301 serialization::Serialize,
302 },
303 crossbeam_epoch::{
304 pin as crossbeam_pin, Atomic, Guard as CrossbeamGuard, Owned, Shared,
305 },
306};
307
308pub use self::{
309 batch::Batch,
310 config::{Config, Mode},
311 db::{open, Db},
312 iter::Iter,
313 ivec::IVec,
314 result::{Error, Result},
315 subscriber::{Event, Subscriber},
316 transaction::Transactional,
317 tree::{CompareAndSwapError, Tree},
318};
319
320use {
321 self::{
322 arc::Arc,
323 atomic_shim::{AtomicI64 as AtomicLsn, AtomicU64},
324 binary_search::binary_search_lub,
325 concurrency_control::Protector,
326 context::Context,
327 fastcmp::fastcmp,
328 histogram::Histogram,
329 lru::Lru,
330 meta::Meta,
331 metrics::{clock, Measure, M},
332 node::{Data, Node},
333 oneshot::{OneShot, OneShotFiller},
334 result::CasResult,
335 subscriber::Subscribers,
336 tree::TreeInner,
337 },
338 crossbeam_utils::{Backoff, CachePadded},
339 log::{debug, error, trace, warn},
340 pagecache::RecoveryGuard,
341 parking_lot::{Condvar, Mutex, RwLock},
342 std::{
343 collections::BTreeMap,
344 convert::TryFrom,
345 fmt::{self, Debug},
346 io::{Read, Write},
347 sync::atomic::{
348 AtomicUsize,
349 Ordering::{Acquire, Release, SeqCst},
350 },
351 },
352};
353
354#[doc(hidden)]
355pub fn pin() -> Guard {
356 Guard { inner: crossbeam_pin(), readset: vec![], writeset: vec![] }
357}
358
359#[doc(hidden)]
360pub struct Guard {
361 inner: CrossbeamGuard,
362 readset: Vec<PageId>,
363 writeset: Vec<PageId>,
364}
365
366impl std::ops::Deref for Guard {
367 type Target = CrossbeamGuard;
368
369 fn deref(&self) -> &CrossbeamGuard {
370 &self.inner
371 }
372}
373
374#[derive(Debug)]
375struct Conflict;
376
377type Conflictable<T> = std::result::Result<T, Conflict>;
378
379fn crc32(buf: &[u8]) -> u32 {
380 let mut hasher = crc32fast::Hasher::new();
381 hasher.update(buf);
382 hasher.finalize()
383}
384
385fn calculate_message_crc32(header: &[u8], body: &[u8]) -> u32 {
386 let mut hasher = crc32fast::Hasher::new();
387 hasher.update(body);
388 hasher.update(&header[4..]);
389 let crc32 = hasher.finalize();
390 crc32 ^ 0xFFFF_FFFF
391}
392
393#[cfg(any(test, feature = "lock_free_delays"))]
394mod debug_delay;
395
396#[cfg(any(test, feature = "lock_free_delays"))]
397use debug_delay::debug_delay;
398
399#[cfg(not(any(test, feature = "lock_free_delays")))]
403const fn debug_delay() {}
404
405#[derive(Clone, Debug, PartialEq)]
408pub(crate) enum Link {
409 Set(IVec, IVec),
411 Del(IVec),
413 ParentMergeIntention(PageId),
415 ParentMergeConfirm,
417 ChildMergeCap,
419}
420
421pub(crate) type FastMap8<K, V> = std::collections::HashMap<
424 K,
425 V,
426 std::hash::BuildHasherDefault<fxhash::FxHasher64>,
427>;
428
429pub(crate) type FastSet8<V> = std::collections::HashSet<
432 V,
433 std::hash::BuildHasherDefault<fxhash::FxHasher64>,
434>;
435
436pub trait MergeOperator:
497 Fn(&[u8], Option<&[u8]>, &[u8]) -> Option<Vec<u8>>
498{
499}
500impl<F> MergeOperator for F where
501 F: Fn(&[u8], Option<&[u8]>, &[u8]) -> Option<Vec<u8>>
502{
503}
504
505mod compile_time_assertions {
506 use crate::*;
507
508 #[allow(unreachable_code)]
509 fn _assert_public_types_send_sync() {
510 _assert_send::<Subscriber>(unreachable!());
511
512 _assert_send_sync::<Iter>(unreachable!());
513 _assert_send_sync::<Tree>(unreachable!());
514 _assert_send_sync::<Db>(unreachable!());
515 _assert_send_sync::<Batch>(unreachable!());
516 _assert_send_sync::<IVec>(unreachable!());
517 _assert_send_sync::<Config>(unreachable!());
518 _assert_send_sync::<CompareAndSwapError>(unreachable!());
519 _assert_send_sync::<Error>(unreachable!());
520 _assert_send_sync::<Event>(unreachable!());
521 _assert_send_sync::<Mode>(unreachable!());
522 }
523
524 fn _assert_send<S: Send>(_: &S) {}
525
526 fn _assert_send_sync<S: Send + Sync>(_: &S) {}
527}