Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: CompactTrie.cpp

Issue 29794564: [proof-of-concept] Compact trie (Closed)
Patch Set: Created May 30, 2018, 11:12 a.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | main.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #include <emscripten/bind.h>
2
3 using namespace emscripten;
4
5 class CompactTrieNode {
6 public:
7 ~CompactTrieNode() {
8 CompactTrieNode* child = last_child;
9
10 while (child) {
11 CompactTrieNode* sibling = child->previous_sibling;
12 delete child;
13 child = sibling;
14 }
15 }
16
17 std::string bytes() const {
18 std::string str;
19 const CompactTrieNode* node = this;
20
21 do {
22 str = node->key + str;
23 node = node->parent;
24 } while (node);
25
26 return str;
27 }
28
29 private:
30 std::string key;
31 int value = 0;
32
33 CompactTrieNode* parent = nullptr;
34 CompactTrieNode* last_child = nullptr;
35 CompactTrieNode* previous_sibling = nullptr;
36
37 friend class CompactTrie;
38 };
39
40 class CompactTrie {
41 public:
42 CompactTrie() {}
43
44 CompactTrieNode* set(const std::string& key, int value) {
45 std::string key_ = key;
46 CompactTrieNode* node = &this->root;
47
48 while (!key_.empty()) {
49 CompactTrieNode* child = node->last_child;
50
51 while (child && child->key[0] != key_[0])
52 child = child->previous_sibling;
53
54 if (child) {
55 size_t n = std::max(child->key.length(), key_.length());
Manish Jethani 2018/05/30 11:49:27 This should be std::min
56 size_t i = 0;
Manish Jethani 2018/05/30 14:47:13 This could start at 1 instead of 0.
57
58 for (; i < n && child->key[i] == key_[i]; i++);
59
60 if (i < child->key.length()) {
61 CompactTrieNode* grandchild = new CompactTrieNode();
Manish Jethani 2018/05/30 14:47:13 Here we're basically splitting a child node into c
62 grandchild->key = child->key.substr(i);
63 grandchild->last_child = child->last_child;
64 grandchild->parent = child;
65
66 CompactTrieNode* great_grandchild = grandchild->last_child;
67
68 while (great_grandchild) {
69 great_grandchild->parent = grandchild;
70 great_grandchild = great_grandchild->previous_sibling;
71 }
72
73 child->key = child->key.substr(0, i);
74 child->last_child = grandchild;
75 }
76
77 key_ = key_.substr(i);
78
79 } else {
80 child = new CompactTrieNode();
81 child->key = key_;
82 child->previous_sibling = node->last_child;
83 child->parent = node;
84
85 node->last_child = child;
86
87 key_.clear();
88 }
89
90 node = child;
91 }
92
93 node->value = value;
94 return node;
95 }
96
97 int get(const std::string& key) const {
98 std::string key_ = key;
99 const CompactTrieNode* node = &this->root;
100
101 while (!key_.empty()) {
102 CompactTrieNode* child = node->last_child;
103
104 while (child && child->key[0] != key_[0])
105 child = child->previous_sibling;
106
107 if (child) {
108 size_t n = std::max(child->key.length(), key_.length());
Manish Jethani 2018/05/30 11:49:27 This should be std::min
109 size_t i = 0;
Manish Jethani 2018/05/30 14:47:13 This could start at 1 instead of 0.
110
111 for (; i < n && child->key[i] == key_[i]; i++);
112
113 if (i < child->key.length())
114 return 0;
115
116 key_ = key_.substr(i);
117
118 } else {
119 return 0;
120 }
121
122 node = child;
123 }
124
125 return node->value;
126 }
127
128 private:
129 CompactTrieNode root;
130 };
131
132 EMSCRIPTEN_BINDINGS(CompactTrieNode) {
133 class_<CompactTrieNode>("CompactTrieNode")
134 .function("bytes", &CompactTrieNode::bytes)
135 ;
136 }
137
138 EMSCRIPTEN_BINDINGS(CompactTrie) {
139 class_<CompactTrie>("CompactTrie")
140 .constructor()
141 .function("set", &CompactTrie::set, allow_raw_pointers())
142 .function("get", &CompactTrie::get)
143 ;
144 }
OLDNEW
« no previous file with comments | « no previous file | main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld