1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#[allow(dead_code)]
#[allow(non_camel_case_types)]
pub mod ffi {
use libc::{c_int, c_uchar, c_uint, c_void};
#[repr(C)]
pub struct cdb {
// File descriptor
pub cdb_fd: c_int,
// Datafile size
cdb_fsize: c_uint,
// End of data ptr
cdb_dend: c_uint,
// mmap'ed file memory
cdb_mem: *const c_uchar,
// Found data
cdb_vpos: c_uint,
cdb_vlen: c_uint,
// Found key
cdb_kpos: c_uint,
cdb_klen: c_uint,
}
// Macros defined in C
impl cdb {
#[inline]
pub fn cdb_datapos(&self) -> c_uint {
self.cdb_vpos
}
#[inline]
pub fn cdb_datalen(&self) -> c_uint {
self.cdb_vlen
}
#[inline]
pub fn cdb_keypos(&self) -> c_uint {
self.cdb_kpos
}
#[inline]
pub fn cdb_keylen(&self) -> c_uint {
self.cdb_klen
}
}
#[repr(C)]
pub struct cdb_find {
cdb_cdbp: *mut cdb,
cdb_hval: c_uint,
cdb_htp: *const c_uchar,
cdb_htab: *const c_uchar,
cdb_htend: *const c_uchar,
cdb_httodo: c_uint,
cdb_key: *const c_void,
cdb_klen: c_uint,
}
#[repr(C)]
pub struct cdb_make {
// File descriptor
pub cdb_fd: c_int,
// Data position so far
cdb_dpos: c_uint,
// Record count so far
cdb_rcnt: c_uint,
// Write buffer
cdb_buf: [c_uchar, ..4096],
// Current buf position
cdb_bpos: *mut c_uchar,
// List of arrays of record infos
// OLD: cdb_rl*
cdb_rec: [*mut c_void, ..256],
}
/**
* `CdbPutMode` represents the different behaviours that will be used when
* inserting a key into a database where the key already exists.
*/
#[repr(C)]
pub enum CdbPutMode {
/**
* No duplicate checking will be performed. This is the same as just
* calling `add()`.
*/
Add = 0,
/**
* If the key already exists in the database, it will be removed prior
* to adding the new value. This can be quite slow if the file is
* large, due to having to copy data around.
*/
Replace = 1,
/**
* Insert the key into the database only if the key does not already
* exist. Note that since a simple query of the database only returns
* the first key, this is really only useful to save space in the
* database.
*/
Insert = 2,
/**
* Add the key to the database unconditionally, but also check if it
* already existed.
*
* TODO: what return value does put give?
*/
Warn = 3,
/**
* If the key already exists in the database, zero it out before adding
* this key/value pair. See the comments on `remove()` for some
* caveats regarding zeroing out keys in the database.
*/
Replace0 = 4,
}
#[repr(C)]
pub enum CdbFindMode {
Find = 0, // == CDB_PUT_ADD
Remove = 1, // == CDB_PUT_REPLACE
Fill0 = 4, // == CDB_PUT_REPLACE0
}
#[link(name = "cdb", kind = "static")]
extern "C" {
pub fn cdb_init(cdbp: *mut cdb, fd: c_int) -> c_int;
pub fn cdb_free(cdbp: *mut cdb);
pub fn cdb_read(cdbp: *const cdb, buf: *mut c_void, len: c_uint, pos: c_uint) -> c_int;
pub fn cdb_get(cdbp: *const cdb, len: c_uint, pos: c_uint) -> *const c_void;
pub fn cdb_find(cdbp: *mut cdb, key: *const c_void, klen: c_uint) -> c_int;
pub fn cdb_findinit(cdbfp: *mut cdb_find, cdb: *mut cdb, key: *const c_void, klen: c_uint) -> c_int;
pub fn cdb_findnext(cdbfp: *mut cdb_find) -> c_int;
pub fn cdb_make_start(cdbmp: *mut cdb_make, fd: c_int) -> c_int;
pub fn cdb_make_add(cdbmp: *mut cdb_make, key: *const c_void, klen: c_uint, val: *const c_void, vlen: c_uint) -> c_int;
pub fn cdb_make_exists(cdbmp: *mut cdb_make, key: *const c_void, klen: c_uint) -> c_int;
pub fn cdb_make_find(cdbmp: *mut cdb_make, key: *const c_void, klen: c_uint, mode: CdbFindMode) -> c_int;
pub fn cdb_make_put(cdbmp: *mut cdb_make, key: *const c_void, klen: c_uint, val: *const c_void, vlen: c_uint, mode: CdbPutMode) -> c_int;
pub fn cdb_make_finish(cdbmp: *mut cdb_make) -> c_int;
pub fn cdb_seqnext(cptr: *mut c_uint, cdbp: *mut cdb) -> c_int;
}
// A C macro
pub unsafe fn cdb_seqinit(cptr: *mut c_uint, _cdbp: *mut cdb) {
*cptr = 2048;
}
}