1use sled;
2
3use std::ffi::CString;
4use std::mem;
5use std::ptr;
6use std::slice;
7
8use libc::*;
9
10use sled::{Config, Db, IVec, Iter};
11
12fn leak_buf(v: Vec<u8>, vallen: *mut size_t) -> *mut c_char {
13 unsafe {
14 *vallen = v.len();
15 }
16 let mut bsv = v.into_boxed_slice();
17 let val = bsv.as_mut_ptr() as *mut _;
18 mem::forget(bsv);
19 val
20}
21
22#[no_mangle]
24pub unsafe extern "C" fn sled_create_config() -> *mut Config {
25 Box::into_raw(Box::new(Config::new()))
26}
27
28#[no_mangle]
30pub unsafe extern "C" fn sled_free_config(config: *mut Config) {
31 drop(Box::from_raw(config));
32}
33
34#[no_mangle]
37pub unsafe extern "C" fn sled_config_set_path(
38 config: *mut Config,
39 path: *const c_char,
40) -> *mut Config {
41 let c_str = CString::from_raw(path as *mut _);
42 let value = c_str.into_string().unwrap();
43
44 let config = Box::from_raw(config);
45 Box::into_raw(Box::from(config.path(value)))
46}
47
48#[no_mangle]
50pub unsafe extern "C" fn sled_config_set_cache_capacity(
51 config: *mut Config,
52 capacity: size_t,
53) -> *mut Config {
54 let config = Box::from_raw(config);
55 Box::into_raw(Box::from(config.cache_capacity(capacity as u64)))
56}
57
58#[no_mangle]
60pub unsafe extern "C" fn sled_config_use_compression(
61 config: *mut Config,
62 use_compression: c_uchar,
63) -> *mut Config {
64 let config = Box::from_raw(config);
65 Box::into_raw(Box::from(config.use_compression(use_compression == 1)))
66}
67
68#[no_mangle]
70pub unsafe extern "C" fn sled_config_flush_every_ms(
71 config: *mut Config,
72 flush_every: c_int,
73) -> *mut Config {
74 let val = if flush_every < 0 { None } else { Some(flush_every as u64) };
75 let config = Box::from_raw(config);
76 Box::into_raw(Box::from(config.flush_every_ms(val)))
77}
78
79#[no_mangle]
81pub unsafe extern "C" fn sled_open_db(config: *mut Config) -> *mut Db {
82 let config = Box::from_raw(config);
83 Box::into_raw(Box::new(config.open().unwrap()))
84}
85
86#[no_mangle]
88pub unsafe extern "C" fn sled_close(db: *mut Db) {
89 drop(Box::from_raw(db));
90}
91
92#[no_mangle]
94pub unsafe extern "C" fn sled_free_buf(buf: *mut c_char, sz: size_t) {
95 drop(Vec::from_raw_parts(buf, sz, sz));
96}
97
98#[no_mangle]
100pub unsafe extern "C" fn sled_free_iter(iter: *mut Iter) {
101 drop(Box::from_raw(iter));
102}
103
104#[no_mangle]
106pub unsafe extern "C" fn sled_set(
107 db: *mut Db,
108 key: *const c_uchar,
109 keylen: size_t,
110 val: *const c_uchar,
111 vallen: size_t,
112) {
113 let k = IVec::from(slice::from_raw_parts(key, keylen));
114 let v = IVec::from(slice::from_raw_parts(val, vallen));
115 (*db).insert(k, v).unwrap();
116}
117
118#[no_mangle]
122pub unsafe extern "C" fn sled_get(
123 db: *mut Db,
124 key: *const c_char,
125 keylen: size_t,
126 vallen: *mut size_t,
127) -> *mut c_char {
128 let k = slice::from_raw_parts(key as *const u8, keylen);
129 let res = (*db).get(k);
130 match res {
131 Ok(Some(v)) => leak_buf(v.to_vec(), vallen),
132 Ok(None) => ptr::null_mut(),
133 Err(e) => panic!("{:?}", e),
135 }
136}
137
138#[no_mangle]
140pub unsafe extern "C" fn sled_del(
141 db: *mut Db,
142 key: *const c_char,
143 keylen: size_t,
144) {
145 let k = slice::from_raw_parts(key as *const u8, keylen);
146 (*db).remove(k).unwrap();
147}
148
149#[no_mangle]
156pub unsafe extern "C" fn sled_compare_and_swap(
157 db: *mut Db,
158 key: *const c_char,
159 keylen: size_t,
160 old_val: *const c_uchar,
161 old_vallen: size_t,
162 new_val: *const c_uchar,
163 new_vallen: size_t,
164 actual_val: *mut *const c_uchar,
165 actual_vallen: *mut size_t,
166) -> c_uchar {
167 let k = IVec::from(slice::from_raw_parts(key as *const u8, keylen));
168
169 let old = if old_vallen == 0 {
170 None
171 } else {
172 let copy =
173 IVec::from(slice::from_raw_parts(old_val as *const u8, old_vallen));
174 Some(copy)
175 };
176
177 let new = if new_vallen == 0 {
178 None
179 } else {
180 let copy =
181 IVec::from(slice::from_raw_parts(new_val as *const u8, new_vallen));
182 Some(copy)
183 };
184
185 let res = (*db).compare_and_swap(k, old, new);
186
187 match res {
188 Ok(Ok(())) => 1,
189 Ok(Err(sled::CompareAndSwapError { current: None, .. })) => {
190 *actual_vallen = 0;
191 0
192 }
193 Ok(Err(sled::CompareAndSwapError { current: Some(v), .. })) => {
194 *actual_val = leak_buf(v.to_vec(), actual_vallen) as *const u8;
195 0
196 }
197 Err(e) => panic!("{:?}", e),
199 }
200}
201
202#[no_mangle]
206pub unsafe extern "C" fn sled_scan_prefix(
207 db: *mut Db,
208 key: *const c_char,
209 keylen: size_t,
210) -> *mut Iter {
211 let k = slice::from_raw_parts(key as *const u8, keylen);
212 Box::into_raw(Box::new((*db).scan_prefix(k)))
213}
214
215#[no_mangle]
219pub unsafe extern "C" fn sled_iter_next(
220 iter: *mut Iter,
221 key: *mut *const c_char,
222 keylen: *mut size_t,
223 val: *mut *const c_char,
224 vallen: *mut size_t,
225) -> c_uchar {
226 match (*iter).next() {
227 Some(Ok((k, v))) => {
228 *key = leak_buf(k.to_vec(), keylen);
229 *val = leak_buf(v.to_vec(), vallen);
230 1
231 }
232 Some(Err(e)) => panic!("{:?}", e),
234 None => 0,
235 }
236}