| Left: | ||
| Right: |
| OLD | NEW |
|---|---|
| (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 } | |
| OLD | NEW |