-
Notifications
You must be signed in to change notification settings - Fork 14
/
Copy pathdbm_leveldb.cpp
112 lines (96 loc) · 2.91 KB
/
dbm_leveldb.cpp
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
#include <cassert>
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
#include "dbm_common.h"
#include "dbm_solver.h"
#include "dbm_cache.h"
extern "C" void fc_solve_dbm_store_init(fcs_dbm_store *store, const char *path)
{
leveldb::DB *db;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options, path, &db);
assert(status.ok());
*store = (fcs_dbm_store)db;
}
extern "C" bool fc_solve_dbm_store_does_key_exist(
fcs_dbm_store store, const unsigned char *key_raw)
{
leveldb::Slice key((const char *)(key_raw + 1), key_raw[0]);
std::string value;
return ((leveldb::DB *)store)
->Get(leveldb::ReadOptions(), key, &value)
.ok();
}
bool fc_solve_dbm_store_lookup_parent_and_move(fcs_dbm_store store,
const unsigned char *key_raw, unsigned char *parent_and_move)
{
leveldb::Slice key((const char *)(key_raw + 1), key_raw[0]);
std::string value;
leveldb::Status status =
((leveldb::DB *)store)->Get(leveldb::ReadOptions(), key, &value);
if (status.ok())
{
memcpy(parent_and_move + 1, value.data() + 1,
(parent_and_move[0] = value.length() - 1) + 1);
return true;
}
else
{
return false;
}
}
#define MAX_ITEMS_IN_TRANSACTION 10000
extern "C" void fc_solve_dbm_store_offload_pre_cache(
fcs_dbm_store store, fcs_pre_cache_t *pre_cache)
{
leveldb::DB *db;
#ifdef FCS_DBM_USE_LIBAVL
struct avl_traverser trav;
dict_key_t item;
#else
dnode_t *node;
#endif
dict_t *kaz_tree;
int num_left_in_transaction = MAX_ITEMS_IN_TRANSACTION;
leveldb::WriteBatch batch;
fcs_pre_cache_key_val_pair_t *kv;
db = (leveldb::DB *)store;
kaz_tree = pre_cache->kaz_tree;
#ifdef FCS_DBM_USE_LIBAVL
avl_t_init(&trav, kaz_tree);
#endif
#ifdef FCS_DBM_USE_LIBAVL
for (item = avl_t_first(&trav, kaz_tree); item; item = avl_t_next(&trav))
#else
for (node = fc_solve_kaz_tree_first(kaz_tree); node;
node = fc_solve_kaz_tree_next(kaz_tree, node))
#define item (node->dict_key)
#endif
{
kv = (fcs_pre_cache_key_val_pair_t *)(item);
leveldb::Slice key((const char *)(kv->key.s + 1), kv->key.s[0]);
// We add 1 to the parent and move's length because it includes the
// trailing one-char move.
leveldb::Slice parent_and_move(
(const char *)(kv->parent_and_move.s + 1),
kv->parent_and_move.s[0] + 1);
batch.Put(key, parent_and_move);
if ((--num_left_in_transaction) <= 0)
{
#define WRITE() assert(db->Write(leveldb::WriteOptions(), &batch).ok())
WRITE();
batch.Clear();
num_left_in_transaction = MAX_ITEMS_IN_TRANSACTION;
}
}
WRITE();
#undef WRITE
}
#ifndef FCS_DBM_USE_LIBAVL
#undef item
#endif
extern "C" void fc_solve_dbm_store_destroy(fcs_dbm_store store)
{
delete ((leveldb::DB *)store);
}