forked from cheyuanl/json_query_cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
graph_storage.cpp
128 lines (109 loc) · 3.32 KB
/
graph_storage.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include "graph_storage.hpp"
#include "util.hpp"
void Node::debug_print(int level = 0) {
for (const auto &e : map) {
for (int k = 0; k < level; k++) {
cout << " ";
}
cout << "key: " << e.first << endl;
e.second->debug_print(level + 2);
}
}
void Node::create_index(const rid &it, Json::Value root) {
// list, cannot be hashed anymore.
if (root.isArray()) {
leafs.push_back(pair<Json::Value, rid>(root, it));
return;
}
// value (i.e. string, int, float, etc, hash its string representation.
if (!root.size()) {
string key = root.asString();
if (map.find(key) == map.end()) {
map[key] = shared_ptr<Node>(new Node());
}
map[key]->leafs.push_back(pair<Json::Value, rid>(root, it));
return;
}
// object (expand the tree)
for (const string &key : root.getMemberNames()) {
if (map.find(key) == map.end()) {
map[key] = shared_ptr<Node>(new Node());
}
map[key]->create_index(it, root[key]);
}
}
void Node::collect_index(list<pair<Json::Value, rid> > &min_leafs,
Json::Value query) {
// list, cannot be hashed anymore.
if (query.isArray()) {
if (min_leafs.empty() || leafs.size() < min_leafs.size()) {
min_leafs = leafs;
}
return;
}
// value (i.e. string, int, float, etc, hash its string representation.
if (!query.size()) {
string key = query.asString();
if (map.find(key) != map.end()) {
if (min_leafs.empty() ||
map[key]->leafs.size() < min_leafs.size()) {
min_leafs = map[key]->leafs;
}
}
return;
}
// object (keep searching the tree)
for (const string &key : query.getMemberNames()) {
if (map.find(key) != map.end()) {
map[key]->collect_index(min_leafs, query[key]);
}
}
return;
}
bool GraphStorage::add(const string &s) {
storage.push_back(s);
rid it = storage.end();
Json::Value data = to_json(s);
root.create_index(--it, data);
return true;
}
/**
* First find the minium subset of documents (leaf) that matches the query.
* Then do linear search within the subset.
*/
vector<string> GraphStorage::get(const string &s) {
Json::Value query = to_json(s);
vector<string> output;
if (query.empty()) {
for (const string &s : storage) {
if (!s.empty()) {
output.push_back(s);
}
}
return output;
}
list<pair<Json::Value, rid> > min_leafs;
root.collect_index(min_leafs, query);
// TODO: better way to mark deletion?
for (pair<Json::Value, rid> p : min_leafs) {
if (!p.second->empty() && match(to_json(*(p.second)), query)) {
output.push_back(*(p.second));
}
}
return output;
}
bool GraphStorage::del(const string &s) {
Json::Value query = to_json(s);
if (query.empty()) {
return true;
}
list<pair<Json::Value, rid> > min_leafs;
root.collect_index(min_leafs, query);
// TODO: better way to mark deletion?
for (pair<Json::Value, rid> p : min_leafs) {
if (!p.second->empty() && match(to_json(*(p.second)), query)) {
p.second->clear();
}
}
return true;
}