ckb_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<'a> Send for SstFileWriter<'a> {}
31unsafe impl<'a> Sync for SstFileWriter<'a> {}
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(
72 &path,
73 "Failed to convert path to CString when create SstFileWriter.",
74 )?;
75 self.open_raw(&cpath)
76 }
77
78 fn open_raw(&'a self, cpath: &CString) -> Result<(), Error> {
79 unsafe {
80 ffi_try!(ffi::rocksdb_sstfilewriter_open(
81 self.inner,
82 cpath.as_ptr() as *const _
83 ));
84
85 Ok(())
86 }
87 }
88
89 pub fn finish(&mut self) -> Result<(), Error> {
91 unsafe {
92 ffi_try!(ffi::rocksdb_sstfilewriter_finish(self.inner,));
93 Ok(())
94 }
95 }
96
97 pub fn file_size(&self) -> u64 {
99 let mut file_size: u64 = 0;
100 unsafe {
101 ffi::rocksdb_sstfilewriter_file_size(self.inner, &mut file_size);
102 }
103 file_size
104 }
105
106 pub fn put<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
109 where
110 K: AsRef<[u8]>,
111 V: AsRef<[u8]>,
112 {
113 let key = key.as_ref();
114 let value = value.as_ref();
115
116 unsafe {
117 ffi_try!(ffi::rocksdb_sstfilewriter_put(
118 self.inner,
119 key.as_ptr() as *const c_char,
120 key.len() as size_t,
121 value.as_ptr() as *const c_char,
122 value.len() as size_t,
123 ));
124 Ok(())
125 }
126 }
127
128 pub fn merge<K, V>(&mut self, key: K, value: V) -> Result<(), Error>
131 where
132 K: AsRef<[u8]>,
133 V: AsRef<[u8]>,
134 {
135 let key = key.as_ref();
136 let value = value.as_ref();
137
138 unsafe {
139 ffi_try!(ffi::rocksdb_sstfilewriter_merge(
140 self.inner,
141 key.as_ptr() as *const c_char,
142 key.len() as size_t,
143 value.as_ptr() as *const c_char,
144 value.len() as size_t,
145 ));
146 Ok(())
147 }
148 }
149
150 pub fn delete<K: AsRef<[u8]>>(&mut self, key: K) -> Result<(), Error> {
153 let key = key.as_ref();
154
155 unsafe {
156 ffi_try!(ffi::rocksdb_sstfilewriter_delete(
157 self.inner,
158 key.as_ptr() as *const c_char,
159 key.len() as size_t,
160 ));
161 Ok(())
162 }
163 }
164}
165
166impl<'a> Drop for SstFileWriter<'a> {
167 fn drop(&mut self) {
168 unsafe {
169 ffi::rocksdb_sstfilewriter_destroy(self.inner);
170 }
171 }
172}