leveldb/database/slice.rs
1//! Core interface for exchanging data with LevelDB.
2//!
3//! It maintains a unified interface when reading from or writing to LevelDB instances.
4//! When creating new instance of Slice, no data copied at Rust layer.
5use super::bytes::Bytes;
6
7/// Slice is the core interface for exchanging data with LevelDB.
8///
9/// Slice can exist in one of two states:
10/// - Borrowed: References a byte array
11/// - Owned: Owns LevelDB-allocated byte data
12///
13/// # Data Access
14///
15/// Use the [`as_bytes()`](Slice::as_bytes) method to obtain a reference to the internal data.
16///
17/// # Important: Iterator Lifetime Warning
18///
19/// When a Slice is returned from an iterator, it **only holds a reference to LevelDB's internal data**.
20/// After the iterator continues iteration (calling next(), seek(), etc.), the data references
21/// in previously returned Slices may become invalid. If longer ownership is required, consider copying the data:
22///
23/// # Memory Management
24///
25/// - Borrowed state: Slice does not own data, lifetime must not exceed original data
26/// - Owned state: Slice owns LevelDB-allocated memory and automatically frees it on Drop
27pub struct Slice<'a> {
28 inner: SliceInner<'a>,
29}
30
31enum SliceInner<'a> {
32 Borrowed(&'a [u8]),
33 Owned(Bytes),
34}
35
36impl<'a> From<&'a [u8]> for Slice<'a> {
37 /// Create a Slice from a byte slice.
38 ///
39 /// This constructor is intended for creating Slice instances from user owned data.
40 /// The Slice will borrow the data, so the original data must outlive the Slice.
41 ///
42 /// Use this when user owned byte data needs to be passed to LevelDB operations
43 /// like put(), delete(), or get(). The Slice will only hold a reference, avoiding data copying.
44 fn from(data: &'a [u8]) -> Self {
45 Slice {
46 inner: SliceInner::Borrowed(data),
47 }
48 }
49}
50
51impl From<Bytes> for Slice<'static> {
52 /// Create a Slice from LevelDB-allocated bytes.
53 ///
54 /// This is used internally to wrap data that LevelDB allocates and returns to the
55 /// Rust layer. The Slice becomes responsible for managing the memory and ensuring
56 /// it's properly freed when no longer needed.
57 fn from(bytes: Bytes) -> Self {
58 Slice {
59 inner: SliceInner::Owned(bytes),
60 }
61 }
62}
63
64impl<'a> std::fmt::Debug for Slice<'a> {
65 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
66 write!(f, "Slice({:?})", self.as_bytes())
67 }
68}
69
70impl<'a> PartialEq for Slice<'a> {
71 fn eq(&self, other: &Self) -> bool {
72 self.as_bytes() == other.as_bytes()
73 }
74}
75
76impl<'a> Eq for Slice<'a> {}
77
78impl<'a> PartialOrd for Slice<'a> {
79 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
80 Some(self.cmp(other))
81 }
82}
83
84impl<'a> Ord for Slice<'a> {
85 fn cmp(&self, other: &Self) -> std::cmp::Ordering {
86 self.as_bytes().cmp(other.as_bytes())
87 }
88}
89
90impl<'a> Slice<'a> {
91 /// Get a byte slice reference to the internal data.
92 ///
93 /// # Returns
94 ///
95 /// Returns a `&[u8]` reference to the internal data. Regardless of whether the Slice
96 /// is in Borrowed or Owned state, the actual data content can be accessed through this method.
97 ///
98 /// # Important Lifetime Warning
99 ///
100 /// **Critical**: If this Slice comes from an iterator, the returned reference's lifetime
101 /// is limited by the iterator's state. This reference may become invalid after the iterator
102 /// continues iteration.
103 pub fn as_bytes(&self) -> &[u8] {
104 match &self.inner {
105 SliceInner::Borrowed(data) => data,
106 SliceInner::Owned(bytes) => bytes.as_ref(),
107 }
108 }
109}
110
111//
112// Useful methods when comparing with other types of data
113//
114
115impl<'a> PartialEq<Vec<u8>> for Slice<'a> {
116 fn eq(&self, other: &Vec<u8>) -> bool {
117 self.as_bytes() == other.as_slice()
118 }
119}
120
121impl<'a> PartialEq<&[u8]> for Slice<'a> {
122 fn eq(&self, other: &&[u8]) -> bool {
123 self.as_bytes() == *other
124 }
125}
126
127impl<'a> PartialEq<Slice<'a>> for Vec<u8> {
128 fn eq(&self, other: &Slice<'a>) -> bool {
129 self.as_slice() == other.as_bytes()
130 }
131}
132
133impl<'a> PartialEq<Slice<'a>> for &[u8] {
134 fn eq(&self, other: &Slice<'a>) -> bool {
135 *self == other.as_bytes()
136 }
137}
138
139impl<const N: usize> PartialEq<[u8; N]> for Slice<'_> {
140 fn eq(&self, other: &[u8; N]) -> bool {
141 self.as_bytes() == other.as_slice()
142 }
143}
144
145impl<const N: usize> PartialEq<Slice<'_>> for [u8; N] {
146 fn eq(&self, other: &Slice<'_>) -> bool {
147 self.as_slice() == other.as_bytes()
148 }
149}