Index: trunk/willow/src/include/dbwrap.h |
— | — | @@ -24,7 +24,67 @@ |
25 | 25 | |
26 | 26 | namespace db { |
27 | 27 | |
28 | | -template<typename Key, typename Value> |
| 28 | +template<typename T> |
| 29 | +struct marshaller { |
| 30 | +}; |
| 31 | + |
| 32 | +template<> |
| 33 | +struct marshaller<char> { |
| 34 | + pair<char const *, uint32_t> marshall(char c) { |
| 35 | + return make_pair(&c, sizeof(c)); |
| 36 | + } |
| 37 | +}; |
| 38 | + |
| 39 | +template<> |
| 40 | +struct marshaller<int> { |
| 41 | + pair<char const *, uint32_t> marshall(int c) { |
| 42 | + return make_pair((char const *)&c, sizeof(c)); |
| 43 | + } |
| 44 | +}; |
| 45 | + |
| 46 | +template<> |
| 47 | +struct marshaller<long> { |
| 48 | + pair<char const *, uint32_t> marshall(long c) { |
| 49 | + return make_pair((char const *)&c, sizeof(c)); |
| 50 | + } |
| 51 | +}; |
| 52 | + |
| 53 | +template<> |
| 54 | +struct marshaller<unsigned long> { |
| 55 | + pair<char const *, uint32_t> marshall(unsigned long c) { |
| 56 | + return make_pair((char const *)&c, sizeof(c)); |
| 57 | + } |
| 58 | +}; |
| 59 | + |
| 60 | +template<> |
| 61 | +struct marshaller<unsigned int> { |
| 62 | + pair<char const *, uint32_t> marshall(unsigned int c) { |
| 63 | + return make_pair((char const *)&c, sizeof(c)); |
| 64 | + } |
| 65 | +}; |
| 66 | + |
| 67 | +template<> |
| 68 | +struct marshaller<string> { |
| 69 | + pair<char const *, uint32_t> marshall(string const &s) { |
| 70 | + return make_pair(s.data(), s.size()); |
| 71 | + } |
| 72 | +}; |
| 73 | + |
| 74 | +template<typename T> |
| 75 | +struct inline_data_store { |
| 76 | + pair<char const *, uint32_t> store(T const &o) { |
| 77 | + marshaller<T> m; |
| 78 | + return m.marshall(o); |
| 79 | + } |
| 80 | + |
| 81 | + T *retrieve(pair<char const *, uint32_t> const &d) { |
| 82 | + marshaller<T> m; |
| 83 | + return m.unmarshall(d); |
| 84 | + } |
| 85 | +}; |
| 86 | + |
| 87 | + |
| 88 | +template<typename Key, typename Value, typename Datastore = inline_data_store<Value> > |
29 | 89 | struct database; |
30 | 90 | struct transaction; |
31 | 91 | |
— | — | @@ -35,9 +95,13 @@ |
36 | 96 | |
37 | 97 | template<typename Key, typename Value> |
38 | 98 | database<Key, Value> *open_database(string const &path); |
| 99 | + template<typename Key, typename Value, typename Datastore> |
| 100 | + database<Key, Value, Datastore> *open_database(string const &path); |
39 | 101 | |
40 | 102 | template<typename Key, typename Value> |
41 | 103 | database<Key, Value> *create_database(string const &path); |
| 104 | + template<typename Key, typename Value, typename Datastore> |
| 105 | + database<Key, Value, Datastore> *create_database(string const &path); |
42 | 106 | |
43 | 107 | int error (void) const; |
44 | 108 | string strerror (void) const; |
— | — | @@ -46,7 +110,7 @@ |
47 | 111 | struct transaction *transaction(void); |
48 | 112 | |
49 | 113 | private: |
50 | | - template<typename Key, typename Value> |
| 114 | + template<typename Key, typename Value, typename Datastore> |
51 | 115 | friend struct database; |
52 | 116 | friend struct transaction; |
53 | 117 | |
— | — | @@ -56,7 +120,7 @@ |
57 | 121 | int _error; |
58 | 122 | }; |
59 | 123 | |
60 | | -template<typename Key, typename Value> |
| 124 | +template<typename Key, typename Value, typename Datastore> |
61 | 125 | struct database : noncopyable { |
62 | 126 | int error (void) const; |
63 | 127 | string strerror (void) const; |
— | — | @@ -91,7 +155,7 @@ |
92 | 156 | |
93 | 157 | private: |
94 | 158 | friend struct environment; |
95 | | - template<typename Key, typename Value> |
| 159 | + template<typename Key, typename Value, typename Datastore> |
96 | 160 | friend struct database; |
97 | 161 | |
98 | 162 | transaction(environment *); |
— | — | @@ -127,7 +191,6 @@ |
128 | 192 | void append(basic_string<charT, traits, allocator> const &); |
129 | 193 | |
130 | 194 | void append_bytes(char const *buf, size_t s) { |
131 | | -std::cout<<"appending "<<s<<" bytes\n"; |
132 | 195 | assert(_size + s <= _bufsz); |
133 | 196 | memcpy(_buf + _size, buf, s); |
134 | 197 | _size += s; |
— | — | @@ -148,7 +211,6 @@ |
149 | 212 | bool extract(basic_string<charT, traits, allocator> &); |
150 | 213 | |
151 | 214 | bool extract_bytes(char *b, size_t s) { |
152 | | -std::cout<<"extracting "<<s<<" bytes\n"; |
153 | 215 | if (_size + s > _bufsz) |
154 | 216 | return false; |
155 | 217 | memcpy(b, _buf + _size, s); |
— | — | @@ -165,21 +227,11 @@ |
166 | 228 | |
167 | 229 | template<typename T> |
168 | 230 | void |
169 | | -marshalling_buffer::append(T const &o) { |
| 231 | +marshalling_buffer::append(T const &o) |
| 232 | +{ |
170 | 233 | append_bytes((char const *)&o, sizeof(o)); |
171 | 234 | } |
172 | 235 | |
173 | | -template<> |
174 | | -void |
175 | | -marshalling_buffer::append<imstring>(imstring const &o); |
176 | | - |
177 | | -template<typename charT, typename traits, typename allocator> |
178 | | -void |
179 | | -marshalling_buffer::append(basic_string<charT, traits, allocator> const &s) { |
180 | | - append<size_t>(s.size() * sizeof(charT)); |
181 | | - append_bytes(s.data(), s.size() * sizeof(charT)); |
182 | | -} |
183 | | - |
184 | 236 | template<typename T> |
185 | 237 | bool |
186 | 238 | marshalling_buffer::extract(T &o) |
— | — | @@ -187,72 +239,18 @@ |
188 | 240 | return extract_bytes((char *) &o, sizeof(o)); |
189 | 241 | } |
190 | 242 | |
191 | | -template<typename charT, typename traits, typename allocator> |
192 | | -bool |
193 | | -marshalling_buffer::extract(basic_string<charT, traits, allocator> &s) |
| 243 | +template<typename Key, typename Value> |
| 244 | +database<Key, Value> * |
| 245 | +environment::open_database(string const &name) |
194 | 246 | { |
195 | | -size_t sz; |
196 | | - if (!extract<size_t>(sz)) |
197 | | - return false; |
198 | | - if (_size + sz > _bufsz) |
199 | | - return false; |
200 | | - s.reserve(sz); |
201 | | - copy(_buf + _size, _buf + _size + sz, back_inserter<charT>(s)); |
202 | | - _size += sz; |
203 | | - return true; |
| 247 | + return new database<Key, Value>(this, name, 0); |
204 | 248 | } |
205 | 249 | |
206 | | -template<typename T> |
207 | | -struct marshaller { |
208 | | -}; |
209 | | - |
210 | | -template<> |
211 | | -struct marshaller<char> { |
212 | | - pair<char const *, uint32_t> marshall(char c) { |
213 | | - return make_pair(&c, sizeof(c)); |
214 | | - } |
215 | | -}; |
216 | | - |
217 | | -template<> |
218 | | -struct marshaller<int> { |
219 | | - pair<char const *, uint32_t> marshall(int c) { |
220 | | - return make_pair((char const *)&c, sizeof(c)); |
221 | | - } |
222 | | -}; |
223 | | - |
224 | | -template<> |
225 | | -struct marshaller<long> { |
226 | | - pair<char const *, uint32_t> marshall(long c) { |
227 | | - return make_pair((char const *)&c, sizeof(c)); |
228 | | - } |
229 | | -}; |
230 | | - |
231 | | -template<> |
232 | | -struct marshaller<unsigned long> { |
233 | | - pair<char const *, uint32_t> marshall(unsigned long c) { |
234 | | - return make_pair((char const *)&c, sizeof(c)); |
235 | | - } |
236 | | -}; |
237 | | - |
238 | | -template<> |
239 | | -struct marshaller<unsigned int> { |
240 | | - pair<char const *, uint32_t> marshall(unsigned int c) { |
241 | | - return make_pair((char const *)&c, sizeof(c)); |
242 | | - } |
243 | | -}; |
244 | | - |
245 | | -template<> |
246 | | -struct marshaller<string> { |
247 | | - pair<char const *, uint32_t> marshall(string const &s) { |
248 | | - return make_pair(s.data(), s.size()); |
249 | | - } |
250 | | -}; |
251 | | - |
252 | | -template<typename Key, typename Value> |
253 | | -database<Key, Value> * |
| 250 | +template<typename Key, typename Value, typename Datastore> |
| 251 | +database<Key, Value, Datastore> * |
254 | 252 | environment::open_database(string const &name) |
255 | 253 | { |
256 | | - return new database<Key, Value>(this, name, 0); |
| 254 | + return new database<Key, Value, Datastore>(this, name, 0); |
257 | 255 | } |
258 | 256 | |
259 | 257 | template<typename Key, typename Value> |
— | — | @@ -262,8 +260,15 @@ |
263 | 261 | return new database<Key, Value>(this, name, DB_CREATE); |
264 | 262 | } |
265 | 263 | |
266 | | -template<typename Key, typename Value> |
267 | | -database<Key, Value>::database(environment *env, string const &path, uint32_t flags) |
| 264 | +template<typename Key, typename Value, typename Datastore> |
| 265 | +database<Key, Value, Datastore> * |
| 266 | +environment::create_database(string const &name) |
| 267 | +{ |
| 268 | + return new database<Key, Value, Datastore>(this, name, DB_CREATE); |
| 269 | +} |
| 270 | + |
| 271 | +template<typename Key, typename Value, typename Datastore> |
| 272 | +database<Key, Value, Datastore>::database(environment *env, string const &path, uint32_t flags) |
268 | 273 | : _env(env) |
269 | 274 | { |
270 | 275 | _error = db_create(&_db, env->_env, 0); |
— | — | @@ -284,9 +289,9 @@ |
285 | 290 | _db->set_errcall(_db, &database::errcall); |
286 | 291 | } |
287 | 292 | |
288 | | -template<typename Key, typename Value> |
| 293 | +template<typename Key, typename Value, typename Datastore> |
289 | 294 | void |
290 | | -database<Key, Value>::errcall(DB_ENV const *, char const *pfx, char const *msg) |
| 295 | +database<Key, Value, Datastore>::errcall(DB_ENV const *, char const *pfx, char const *msg) |
291 | 296 | { |
292 | 297 | if (pfx) |
293 | 298 | wlog(WLOG_WARNING, format("%s: %s") % pfx % msg); |
— | — | @@ -294,37 +299,37 @@ |
295 | 300 | wlog(WLOG_WARNING, msg); |
296 | 301 | } |
297 | 302 | |
298 | | -template<typename Key, typename Value> |
| 303 | +template<typename Key, typename Value, typename Datastore> |
299 | 304 | int |
300 | | -database<Key, Value>::error(void) const |
| 305 | +database<Key, Value, Datastore>::error(void) const |
301 | 306 | { |
302 | 307 | return _error; |
303 | 308 | } |
304 | 309 | |
305 | | -template<typename Key, typename Value> |
| 310 | +template<typename Key, typename Value, typename Datastore> |
306 | 311 | string |
307 | | -database<Key, Value>::strerror(void) const |
| 312 | +database<Key, Value, Datastore>::strerror(void) const |
308 | 313 | { |
309 | 314 | return db_strerror(_error); |
310 | 315 | } |
311 | 316 | |
312 | | -template<typename Key, typename Value> |
313 | | -database<Key, Value>::~database(void) |
| 317 | +template<typename Key, typename Value, typename Datastore> |
| 318 | +database<Key, Value, Datastore>::~database(void) |
314 | 319 | { |
315 | 320 | if (_db) |
316 | 321 | _db->close(_db, 0); |
317 | 322 | } |
318 | 323 | |
319 | | -template<typename Key, typename Value> |
| 324 | +template<typename Key, typename Value, typename Datastore> |
320 | 325 | bool |
321 | | -database<Key, Value>::put(Key const &key, Value const &value) |
| 326 | +database<Key, Value, Datastore>::put(Key const &key, Value const &value) |
322 | 327 | { |
323 | 328 | return put (key, value, NULL); |
324 | 329 | } |
325 | 330 | |
326 | | -template<typename Key, typename Value> |
| 331 | +template<typename Key, typename Value, typename Datastore> |
327 | 332 | bool |
328 | | -database<Key, Value>::put(Key const &key, Value const &value, transaction *txn) |
| 333 | +database<Key, Value, Datastore>::put(Key const &key, Value const &value, transaction *txn) |
329 | 334 | { |
330 | 335 | pair<char const *, uint32_t> mkey, mvalue; |
331 | 336 | DBT dbkey, dbvalue; |
— | — | @@ -348,16 +353,16 @@ |
349 | 354 | return true; |
350 | 355 | } |
351 | 356 | |
352 | | -template<typename Key, typename Value> |
| 357 | +template<typename Key, typename Value, typename Datastore> |
353 | 358 | Value * |
354 | | -database<Key, Value>::get(Key const &key) |
| 359 | +database<Key, Value, Datastore>::get(Key const &key) |
355 | 360 | { |
356 | 361 | return get(key, NULL); |
357 | 362 | } |
358 | 363 | |
359 | | -template<typename Key, typename Value> |
| 364 | +template<typename Key, typename Value, typename Datastore> |
360 | 365 | Value * |
361 | | -database<Key, Value>::get(Key const &key, transaction *txn) |
| 366 | +database<Key, Value, Datastore>::get(Key const &key, transaction *txn) |
362 | 367 | { |
363 | 368 | pair<char const *, uint32_t> mkey; |
364 | 369 | DBT dbkey, dbvalue; |
— | — | @@ -379,9 +384,9 @@ |
380 | 385 | return ret; |
381 | 386 | } |
382 | 387 | |
383 | | -template<typename Key, typename Value> |
| 388 | +template<typename Key, typename Value, typename Datastore> |
384 | 389 | void |
385 | | -database<Key, Value>::close(void) |
| 390 | +database<Key, Value, Datastore>::close(void) |
386 | 391 | { |
387 | 392 | _db->close(_db, 0); |
388 | 393 | _db = NULL; |