rocksdb/
sst_file_writer.rs1use crate::{ffi, ffi_util::to_cpath, Error, Options};
17
18use libc::{self, c_char, size_t};
19use std::{ffi::CString, marker::PhantomData, path::Path};
20
21pub struct SstFileWriter<'a> {
24 pub(crate) inner: *mut ffi::rocksdb_sstfilewriter_t,
25 phantom: PhantomData<&'a Options>,
28}
29
30unsafe impl Send for SstFileWriter<'_> {}
31unsafe impl Sync for SstFileWriter<'_> {}
32
33struct EnvOptions {
34 inner: *mut ffi::rocksdb_envoptions_t,
35}
36
37impl Drop for EnvOptions {
38 fn drop(&mut self) {
39 unsafe {
40 ffi::rocksdb_envoptions_destroy(self.inner);
41 }
42 }
43}
44
45impl Default for EnvOptions {
46 fn default() -> Self {
47 let opts = unsafe { ffi::rocksdb_envoptions_create() };
48 Self { inner: opts }
49 }
50}
51
52impl<'a> SstFileWriter<'a> {
53 pub fn create(opts: &'a Options) -> Self {
55 let env_options = EnvOptions::default();
56
57 let writer = Self::create_raw(opts, &env_options);
58
59 Self {
60 inner: writer,
61 phantom: PhantomData,
62 }
63 }
64
65 fn create_raw(opts: &Options, env_opts: &EnvOptions) -> *mut ffi::rocksdb_sstfilewriter_t {
66 unsafe { ffi::rocksdb_sstfilewriter_create(env_opts.inner, opts.inner) }
67 }
68
69 pub fn open<P: AsRef<Path>>(&'a self, path: P) -> Result<(), Error> {
71 let cpath = to_cpath(&path)?;
72 self.open_raw(&cpath)
73 }
74
75 fn open_raw(&'a self, cpath: &CString) -> Result<(), Error> {
76 unsafe {
77 ffi_try!(ffi::rocksdb_sstfilewriter_open(
78 self.inner,
79 cpath.as_ptr() as *const _
80 ));
81
82 Ok(())
83 }
84 }
85
86 pub fn finish(&mut self) -> Result<(), Error> {
88 unsafe {
89 ffi_try!(ffi::rocksdb_sstfilewriter_finish(self.inner,));
90 Ok(())
91 }
92 }
93
94 pub fn file_size(&self) -> u64 {
96 let mut file_size: u64 = 0;
97 unsafe {
98 ffi::rocksdb_sstfilewriter_file_size(self.inner, &mut file_size);
99 }
100 file_size
101 }
102
103 pub fn put<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
106 where
107 K: AsRef<[u8]>,
108 V: AsRef<[u8]>,
109 {
110 let key = key.as_ref();
111 let value = value.as_ref();
112 unsafe {
113 ffi_try!(ffi::rocksdb_sstfilewriter_put(
114 self.inner,
115 key.as_ptr() as *const c_char,
116 key.len() as size_t,
117 value.as_ptr() as *const c_char,
118 value.len() as size_t,
119 ));
120 Ok(())
121 }
122 }
123
124 pub fn put_with_ts<K, V, S>(&mut self, key: K, ts: S, value: V) -> Result<(), Error>
127 where
128 K: AsRef<[u8]>,
129 V: AsRef<[u8]>,
130 S: AsRef<[u8]>,
131 {
132 let key = key.as_ref();
133 let value = value.as_ref();
134 let ts = ts.as_ref();
135 unsafe {
136 ffi_try!(ffi::rocksdb_sstfilewriter_put_with_ts(
137 self.inner,
138 key.as_ptr() as *const c_char,
139 key.len() as size_t,
140 ts.as_ptr() as *const c_char,
141 ts.len() as size_t,
142 value.as_ptr() as *const c_char,
143 value.len() as size_t,
144 ));
145 Ok(())
146 }
147 }
148
149 pub fn merge<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
152 where
153 K: AsRef<[u8]>,
154 V: AsRef<[u8]>,
155 {
156 let key = key.as_ref();
157 let value = value.as_ref();
158
159 unsafe {
160 ffi_try!(ffi::rocksdb_sstfilewriter_merge(
161 self.inner,
162 key.as_ptr() as *const c_char,
163 key.len() as size_t,
164 value.as_ptr() as *const c_char,
165 value.len() as size_t,
166 ));
167 Ok(())
168 }
169 }
170
171 pub fn delete<K: AsRef<[u8]>>(&mut self, key: K) -> Result<(), Error> {
174 let key = key.as_ref();
175
176 unsafe {
177 ffi_try!(ffi::rocksdb_sstfilewriter_delete(
178 self.inner,
179 key.as_ptr() as *const c_char,
180 key.len() as size_t,
181 ));
182 Ok(())
183 }
184 }
185
186 pub fn delete_with_ts<K: AsRef<[u8]>, S: AsRef<[u8]>>(
189 &mut self,
190 key: K,
191 ts: S,
192 ) -> Result<(), Error> {
193 let key = key.as_ref();
194 let ts = ts.as_ref();
195 unsafe {
196 ffi_try!(ffi::rocksdb_sstfilewriter_delete_with_ts(
197 self.inner,
198 key.as_ptr() as *const c_char,
199 key.len() as size_t,
200 ts.as_ptr() as *const c_char,
201 ts.len() as size_t,
202 ));
203 Ok(())
204 }
205 }
206}
207
208impl Drop for SstFileWriter<'_> {
209 fn drop(&mut self) {
210 unsafe {
211 ffi::rocksdb_sstfilewriter_destroy(self.inner);
212 }
213 }
214}