1#![cfg_attr(not(feature = "std"), no_std)]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5#![cfg_attr(docsrs, allow(unused_attributes))]
6#![deny(missing_docs)]
7
8macro_rules! has_prefix {
9 ($trait:tt::$fn:tt) => {
10 #[inline]
12 fn has_prefix(&self, prefix: impl $trait) -> bool {
13 let src = $trait::$fn(self);
14 let prefix = $trait::$fn(&prefix);
15 let pl = prefix.len();
16 if src.len() < pl {
17 return false;
18 }
19
20 src[0..pl].eq(prefix)
21 }
22 };
23}
24
25macro_rules! has_suffix {
26 ($trait:tt::$fn:tt) => {
27 #[inline]
29 fn has_suffix(&self, suffix: impl $trait) -> bool {
30 let src = $trait::$fn(self);
31 let suffix = $trait::$fn(&suffix);
32 let pl = suffix.len() - 1;
33 if src.len() <= pl {
34 return false;
35 }
36
37 src[pl..].eq(suffix)
38 }
39 };
40}
41
42macro_rules! longest_prefix {
43 ($trait:tt::$fn:tt, $ty: ty) => {
44 #[inline]
46 fn longest_prefix(&self, other: impl $trait) -> &[$ty] {
47 let k1 = $trait::$fn(self);
48 let k2 = $trait::$fn(&other);
49 let max = k1.len().min(k2.len());
50
51 let mut n = max - 1;
52 for i in 0..max {
53 if k1[i].ne(&k2[i]) {
54 n = i;
55 break;
56 }
57 }
58 &k1[..n]
59 }
60 };
61}
62
63macro_rules! longest_suffix {
64 ($trait:tt::$fn:tt, $ty: ty) => {
65 #[inline]
67 fn longest_suffix(&self, other: impl $trait) -> &[$ty] {
68 let k1 = $trait::$fn(self);
69 let k1_len = k1.len();
70 let k2 = $trait::$fn(&other);
71 let k2_len = k2.len();
72 return if k1_len < k2_len {
73 let max = k1_len;
74 let mut n = max;
75 for i in 0..max {
76 if k1[k1_len - i - 1].ne(&k2[k2_len - i - 1]) {
77 n = i;
78 break;
79 }
80 }
81 &k1[max - n..]
82 } else {
83 let max = k2_len;
84 let mut n = max;
85 for i in 0..max {
86 if k1[k1_len - i - 1].ne(&k2[k2_len - i - 1]) {
87 n = i;
88 break;
89 }
90 }
91 &k1[k1_len - k2_len + max - n..]
92 };
93 }
94 };
95}
96
97macro_rules! longest_prefix_lossy {
98 ($trait:tt::$fn:tt, $ty: ty, $ty_literal: literal) => {
99 #[doc = concat!("Finds the longest shared prefix, return a Cow<'_, [", $ty_literal, "]>.")]
100 #[inline]
101 fn longest_prefix_lossy(&self, other: impl $trait) -> Cow<'_, [$ty]> {
102 Cow::Borrowed(self.longest_prefix(other))
103 }
104 };
105}
106
107macro_rules! longest_suffix_lossy {
108 ($trait:tt::$fn:tt, $ty: ty, $ty_literal: literal) => {
109 #[doc = concat!("Finds the longest shared suffix, return a Cow<'_, [", $ty_literal, "]>.")]
110 #[inline]
111 fn longest_suffix_lossy(&self, other: impl $trait) -> Cow<'_, [$ty]> {
112 Cow::Borrowed(self.longest_suffix(other))
113 }
114 };
115}
116
117macro_rules! impl_psfix_suites {
118 ($trait:tt::$fn:tt, $ty: ty, $ty_literal: literal) => {
119 has_prefix!($trait::$fn);
120
121 has_suffix!($trait::$fn);
122
123 longest_prefix!($trait::$fn, $ty);
124
125 longest_suffix!($trait::$fn, $ty);
126
127 longest_prefix_lossy!($trait::$fn, $ty, $ty_literal);
128
129 longest_suffix_lossy!($trait::$fn, $ty, $ty_literal);
130 };
131}
132
133macro_rules! cfg_std {
134 ($($item: item)*) => {
135 $(
136 #[cfg(feature = "std")]
137 $item
138 )*
139 };
140}
141
142extern crate alloc;
143
144mod entry;
145mod header;
146pub mod iterator;
148mod key;
149mod key_mut;
150mod raw_entry_pointer;
151mod raw_key_pointer;
152mod raw_value_pointer;
153mod value;
154mod value_enc;
155mod value_mut;
156
157pub mod raw_pointer {
163 pub use crate::raw_entry_pointer::*;
164 pub use crate::raw_key_pointer::*;
165 pub use crate::raw_value_pointer::*;
166}
167pub mod bytes {
171 pub use bytes::*;
172}
173pub use entry::*;
174pub use header::*;
175pub use key::*;
176pub use key_mut::*;
177pub use value::*;
178pub use value_enc::*;
179pub use value_mut::*;
180
181use crate::bytes::{BufMut, BytesMut};
182use alloc::vec::Vec;
183use bitflags::bitflags;
184#[cfg(feature = "std")]
185use header::ByteReader;
186
187const TIMESTAMP_SIZE: usize = core::mem::size_of::<u64>();
188
189bitflags! {
190 pub struct OP: u8 {
193 #[doc = "Set if the key has been deleted."]
194 const BIT_DELETE = 1 << 0;
195 #[doc = "Set if the value is NOT stored directly next to key."]
196 const BIT_VALUE_POINTER = 1 << 1;
197 #[doc = "Set if earlier versions can be discarded."]
198 const BIT_DISCARD_EARLIER_VERSIONS = 1 << 2;
199 #[doc = "Set if item shouldn't be discarded via compactions (used by merge operator)"]
200 const BIT_MERGE_ENTRY = 1 << 3;
201 #[doc = "Set if the entry is part of a txn."]
202 const BIT_TXN = 1 << 6;
203 #[doc = "Set if the entry is to indicate end of txn in value log."]
204 const BIT_FIN_TXN = 1 << 7;
205 }
206}
207
208#[inline]
209fn u64_big_endian(b: &[u8]) -> u64 {
210 (b[7] as u64)
211 | ((b[6] as u64) << 8)
212 | (b[5] as u64) << 16
213 | (b[4] as u64) << 24
214 | (b[3] as u64) << 32
215 | (b[2] as u64) << 40
216 | (b[1] as u64) << 48
217 | (b[0] as u64) << 56
218}
219
220const MAX_VARINT_LEN64: usize = 10;
221
222#[inline]
232fn binary_uvarint(buf: &[u8]) -> (u64, usize) {
233 let mut x = 0;
234 let mut s = 0usize;
235 for (idx, b) in buf.iter().enumerate() {
236 let b = *b;
237 if b < 0x80 {
238 if idx >= MAX_VARINT_LEN64 || idx == MAX_VARINT_LEN64 - 1 && b > 1 {
239 return (0, !(idx + 1)); }
241 return (x | (b as u64) << s, idx + 1);
242 }
243 x |= ((b & 0x7f) as u64) << s;
244 s += 7;
245 }
246 (0, 0)
247}
248
249#[inline]
250fn put_binary_uvariant_to_vec(vec: &mut Vec<u8>, mut x: u64) {
251 while x >= 0x80 {
252 vec.push((x as u8) | 0x80);
253 x >>= 7;
254 }
255 vec.push(x as u8)
256}
257
258#[inline]
259fn binary_put_uvariant_to_bufmut(buf: &mut BytesMut, mut x: u64) -> usize {
260 let mut i = 0;
261 while x >= 0x80 {
262 buf.put_u8((x as u8) | 0x80);
263 x >>= 7;
264 i += 1;
265 }
266 buf.put_u8(x as u8);
267 i + 1
268}
269
270cfg_std! {
271 #[derive(Copy, Clone, Debug)]
273 pub struct Overflow;
274
275 impl std::fmt::Display for Overflow {
276 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
277 write!(f, "binary: variant overflows a 64-bit integer")
278 }
279 }
280
281 impl std::error::Error for Overflow {}
282
283 impl From<Overflow> for std::io::Error {
284 fn from(of: Overflow) -> Self {
285 std::io::Error::new(std::io::ErrorKind::Other, of)
286 }
287 }
288
289 fn binary_read_and_put_uvarint(r: &mut impl ByteReader, dst: &mut BytesMut) -> std::io::Result<u64> {
291 let mut x = 0u64;
292 let mut s = 0usize;
293 for idx in 0..MAX_VARINT_LEN64 {
294 let b = r.read_byte()?;
295 dst.put_u8(b);
296 if b < 0x80 {
297 if idx == MAX_VARINT_LEN64 - 1 && b > 1 {
298 return Err(Overflow.into());
299 }
300 return Ok(x | (b as u64) << s);
301 }
302 x |= ((b & 0x7f) as u64) << s;
303 s += 7;
304 }
305 Ok(x)
306 }
307}
308
309#[inline]
310fn binary_put_uvariant_to_vec(buf: &mut Vec<u8>, mut x: u64) -> usize {
311 let mut i = 0;
312 while x >= 0x80 {
313 buf.push((x as u8) | 0x80);
314 x >>= 7;
315 i += 1;
316 }
317 buf.push(x as u8);
318 i + 1
319}
320
321#[inline]
322fn binary_uvarint_allocate(mut x: u64) -> Vec<u8> {
323 let mut vec = Vec::with_capacity(MAX_VARINT_LEN64);
324 while x >= 0x80 {
325 vec.push((x as u8) | 0x80);
326 x >>= 7;
327 }
328 vec.push(x as u8);
329 vec
330}