1 /**
2  * D-LevelDB Write Batch
3  *
4  * WriteBatch holds multiple writes that can be applied to an open DB in a sinlge
5  * atomic update.
6  *
7  * Copyright: Copyright © 2013 Byron Heads
8  * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>.
9  * Authors: Byron Heads
10 */
11 /*          Copyright  © 2013 Byron Heads
12  * Distributed under the Boost Software License, Version 1.0.
13  *    (See accompanying file LICENSE_1_0.txt or copy at
14  *          http://www.boost.org/LICENSE_1_0.txt)
15  */
16 module leveldb.writebatch;
17 
18 private import  leveldb.exceptions,
19                 leveldb.slice;
20 private import deimos.leveldb.leveldb;
21 
22 class WriteBatch
23 {
24 private:
25     leveldb_writebatch_t _ptr;
26 
27 package:
28     @property
29     inout(leveldb_writebatch_t) ptr() inout
30     {
31         return _ptr;
32     }
33 
34 public:
35     this()
36     {
37         if((_ptr = leveldb_writebatch_create()) is null)
38             throw new LeveldbException("Failed to create batch writer");
39     }
40 
41     ~this()
42     {
43         if(valid)
44         {
45             leveldb_writebatch_destroy(_ptr);
46             _ptr = null;
47         }
48     }
49 
50     @property
51     void clear()
52     {
53         leveldb_writebatch_clear(_ptr);
54     }
55 
56     void put(K, V)(K key, V val)
57     {
58         put_raw(key._lib_obj_ptr__, key._lib_obj_size__, val._lib_obj_ptr__, val._lib_obj_size__);
59     }
60 
61     private
62     void put_raw(const(char*) key, size_t keylen, const(char*)val, size_t vallen)
63     {
64         leveldb_writebatch_put(_ptr, key, keylen, val, vallen);
65     }
66 
67     void del(T)(T key)
68     {
69         leveldb_writebatch_delete(_ptr, key._lib_obj_ptr__, key._lib_obj_size__);
70     }
71 
72     void iterate(Visitor visitor)
73     {
74         leveldb_writebatch_iterate(_ptr, cast(void*)&visitor,
75             &batchPut, &batchDel);
76     }
77 
78     void iterate(void delegate(Slice key, Slice value) puts,
79         void delegate(Slice key) dels)
80     {
81         iterate(Visitor(puts, dels));
82     }
83 
84     @property
85     bool valid() inout
86     {
87         return _ptr !is null;
88     }
89 
90     static struct Visitor
91     {
92         void delegate(Slice key, Slice value) puts;
93         void delegate(Slice key) dels;
94     }
95 } // WriteBatch
96 
97 
98 private:
99 extern(C):
100 
101 void batchPut(void* state, const char* k, size_t klen, const char* v, size_t vlen)
102 {
103     auto visitor = cast(WriteBatch.Visitor*)state;
104     visitor.puts(Slice(cast(void*)k, klen, true), Slice(cast(void*)v, vlen, true));
105 }
106 
107 void batchDel(void* state, const char* k, size_t klen)
108 {
109     auto visitor = cast(WriteBatch.Visitor*)state;
110     visitor.dels(Slice(cast(void*)k, klen, true));
111 }