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

Unified Diff: CompactTrie.cpp

Issue 29794564: [proof-of-concept] Compact trie (Closed)
Patch Set: Created May 30, 2018, 11:12 a.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | main.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: CompactTrie.cpp
===================================================================
new file mode 100644
--- /dev/null
+++ b/CompactTrie.cpp
@@ -0,0 +1,144 @@
+#include <emscripten/bind.h>
+
+using namespace emscripten;
+
+class CompactTrieNode {
+ public:
+ ~CompactTrieNode() {
+ CompactTrieNode* child = last_child;
+
+ while (child) {
+ CompactTrieNode* sibling = child->previous_sibling;
+ delete child;
+ child = sibling;
+ }
+ }
+
+ std::string bytes() const {
+ std::string str;
+ const CompactTrieNode* node = this;
+
+ do {
+ str = node->key + str;
+ node = node->parent;
+ } while (node);
+
+ return str;
+ }
+
+ private:
+ std::string key;
+ int value = 0;
+
+ CompactTrieNode* parent = nullptr;
+ CompactTrieNode* last_child = nullptr;
+ CompactTrieNode* previous_sibling = nullptr;
+
+ friend class CompactTrie;
+};
+
+class CompactTrie {
+ public:
+ CompactTrie() {}
+
+ CompactTrieNode* set(const std::string& key, int value) {
+ std::string key_ = key;
+ CompactTrieNode* node = &this->root;
+
+ while (!key_.empty()) {
+ CompactTrieNode* child = node->last_child;
+
+ while (child && child->key[0] != key_[0])
+ child = child->previous_sibling;
+
+ if (child) {
+ size_t n = std::max(child->key.length(), key_.length());
Manish Jethani 2018/05/30 11:49:27 This should be std::min
+ size_t i = 0;
Manish Jethani 2018/05/30 14:47:13 This could start at 1 instead of 0.
+
+ for (; i < n && child->key[i] == key_[i]; i++);
+
+ if (i < child->key.length()) {
+ CompactTrieNode* grandchild = new CompactTrieNode();
Manish Jethani 2018/05/30 14:47:13 Here we're basically splitting a child node into c
+ grandchild->key = child->key.substr(i);
+ grandchild->last_child = child->last_child;
+ grandchild->parent = child;
+
+ CompactTrieNode* great_grandchild = grandchild->last_child;
+
+ while (great_grandchild) {
+ great_grandchild->parent = grandchild;
+ great_grandchild = great_grandchild->previous_sibling;
+ }
+
+ child->key = child->key.substr(0, i);
+ child->last_child = grandchild;
+ }
+
+ key_ = key_.substr(i);
+
+ } else {
+ child = new CompactTrieNode();
+ child->key = key_;
+ child->previous_sibling = node->last_child;
+ child->parent = node;
+
+ node->last_child = child;
+
+ key_.clear();
+ }
+
+ node = child;
+ }
+
+ node->value = value;
+ return node;
+ }
+
+ int get(const std::string& key) const {
+ std::string key_ = key;
+ const CompactTrieNode* node = &this->root;
+
+ while (!key_.empty()) {
+ CompactTrieNode* child = node->last_child;
+
+ while (child && child->key[0] != key_[0])
+ child = child->previous_sibling;
+
+ if (child) {
+ size_t n = std::max(child->key.length(), key_.length());
Manish Jethani 2018/05/30 11:49:27 This should be std::min
+ size_t i = 0;
Manish Jethani 2018/05/30 14:47:13 This could start at 1 instead of 0.
+
+ for (; i < n && child->key[i] == key_[i]; i++);
+
+ if (i < child->key.length())
+ return 0;
+
+ key_ = key_.substr(i);
+
+ } else {
+ return 0;
+ }
+
+ node = child;
+ }
+
+ return node->value;
+ }
+
+ private:
+ CompactTrieNode root;
+};
+
+EMSCRIPTEN_BINDINGS(CompactTrieNode) {
+ class_<CompactTrieNode>("CompactTrieNode")
+ .function("bytes", &CompactTrieNode::bytes)
+ ;
+}
+
+EMSCRIPTEN_BINDINGS(CompactTrie) {
+ class_<CompactTrie>("CompactTrie")
+ .constructor()
+ .function("set", &CompactTrie::set, allow_raw_pointers())
+ .function("get", &CompactTrie::get)
+ ;
+}
« no previous file with comments | « no previous file | main.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld