From 40a26f9cb474a17b5b802ef306d08813a1266096 Mon Sep 17 00:00:00 2001 From: Kyle Gendreau Date: Thu, 1 Jul 2021 15:37:16 -0500 Subject: [PATCH] fixed some consts and stuff --- include/SimpleTrieTemplate.h | 17 +++++----- src/SimpleTrieTemplate.cpp | 65 +++++++++++++++++++++++------------- 2 files changed, 50 insertions(+), 32 deletions(-) diff --git a/include/SimpleTrieTemplate.h b/include/SimpleTrieTemplate.h index a0c2563..aa516de 100644 --- a/include/SimpleTrieTemplate.h +++ b/include/SimpleTrieTemplate.h @@ -9,6 +9,7 @@ #include #include #include "Iterator.h" +#include "DefaultParameters.h" /** * -1 if cur node's key is equivalent to input, @@ -20,7 +21,7 @@ * -2 if not found */ template -class Awful_Indexer { +class BinTrie_Indexer { public: // called when not inserting int32_t operator()(K& input, const Node* node) { @@ -52,9 +53,9 @@ class SimpleTrieTemplate; * */ template -class Awful_Eraser { +class BinTrie_Eraser { public: - void operator()(Node* &ancestor, Node* &descendant, SimpleTrieTemplate> &trie) { + void operator()(Node* &ancestor, Node* &descendant, SimpleTrieTemplate> &trie) { std::stack> stk; mergeStack(stk, getStack(descendant->child_.at(0).get())); @@ -106,7 +107,7 @@ class Awful_Eraser { } }; -template , typename Eraser = Awful_Eraser> +template , typename Eraser = BinTrie_Eraser> class SimpleTrieTemplate { public: @@ -185,7 +186,7 @@ class SimpleTrieTemplate { * swaps the contents * @param rhs - the container to exchange the contents with */ - void swap(SimpleTrieTemplate& rhs); + void swap(SimpleTrieTemplate& rhs) noexcept; ////////////////////////////////////////////////////// //// LOOKUPS @@ -246,10 +247,10 @@ class SimpleTrieTemplate { ////////////////////////////////////////////////////// //// PRIVATE HELPER METHODS - std::pair scout_helper(key_type& key, const Node* curNode); + static std::pair scout_helper(key_type& key, const Node* curNode, key_indexer& indexer); - iterator insert_helper(Node* &curNode, key_type& article, mapped_type& value); - iterator insert_helper(Node* &&curNode, key_type& article, mapped_type& value); + static iterator insert_helper(Node* &curNode, key_type& article, mapped_type& value, key_indexer& indexer); + static iterator insert_helper(Node* &&curNode, key_type& article, mapped_type& value, key_indexer& indexer); void checkIterPtr_helper(Node* &ptr); diff --git a/src/SimpleTrieTemplate.cpp b/src/SimpleTrieTemplate.cpp index a09cce8..8aabe6b 100644 --- a/src/SimpleTrieTemplate.cpp +++ b/src/SimpleTrieTemplate.cpp @@ -69,22 +69,35 @@ Iterator SimpleTrieTemplate::insertOrAssign(s template Iterator SimpleTrieTemplate::insertOrAssign(key_type article, mapped_type &value, Node* ancestor) { - checkIterPtr_helper(ancestor); - uint32_t cnt(size()); - if (contains(article)) - --cnt; + checkIterPtr_helper(ancestor); // ensure ptr not null, else assign to begin() node + uint32_t cnt(size()); // obtain original size + + auto it(begin()); // will be assigned later + Node* ptr(nullptr); // will be assigned later - auto it(begin()); + // if it's empty, then we insert at root's first child. There should ALWAYS be a root node, it holds junk values. if (empty()) { //ie if curNode == end().get() && curNode == begin().get() assert(ancestor == root_); - Node* ptr(ancestor->child_.at(0).get()); - it = insert_helper(ptr,article,value); + it = insert_helper(ptr,article,value,indexer_); + + // CHANGES ARE NOW PERMANENT -- exception safe ancestor->child_.at(0).reset(ptr); ptr->parent_ = ancestor; } - else - it = insert_helper(ancestor, article, value); + + // else we insert the input directly at the node, not after! + else { + if (contains(article)) // if already present then count shouldn't change + --cnt; + ptr = new Node(*ancestor); + it = insert_helper(ptr, article, value, indexer_); + + // CHANGES ARE NOW PERMANENT -- exception safe + ptr->parent_ = ancestor->parent_; + ancestor->parent_->child_.at(iterator::findChildsIndex(*ancestor->parent_, *ancestor)).reset(ptr); + ancestor = ptr; + } numberArticles_ = ++cnt; return it; @@ -109,13 +122,15 @@ void SimpleTrieTemplate::erase(Node* &descendant,Nod if (!empty()) { uint32_t curSize(size()); checkIterPtr_helper(ancestor); + + // CHANGES ARE NOW PERMANENT -- todo NOT EXCEPTION SAFE eraser_(ancestor, descendant, *this); numberArticles_ = --curSize; } } template -void SimpleTrieTemplate::swap(SimpleTrieTemplate &rhs) { +void SimpleTrieTemplate::swap(SimpleTrieTemplate &rhs) noexcept { if (this != &rhs) { // numberArticles_ std::swap(numberArticles_,rhs.numberArticles_); @@ -140,11 +155,13 @@ Iterator SimpleTrieTemplate::find(key_type ar template std::pair> SimpleTrieTemplate::scout(key_type article,Node* ancestor) { - if (empty()) { + if (empty()) return std::pair(false,begin()); - } + checkIterPtr_helper(ancestor); - return scout_helper(article, ancestor); + + // assume scout operation doesn't edit nodes in trie + return scout_helper(article, ancestor, indexer_); } template @@ -181,19 +198,20 @@ Iterator SimpleTrieTemplate::end() { template std::pair> -SimpleTrieTemplate::scout_helper(key_type &key, const Node* curNode) { - int32_t index(indexer_(key,curNode)); +SimpleTrieTemplate::scout_helper(key_type &key, const Node* curNode, key_indexer& indexer) { + + int32_t index(indexer(key,curNode)); if (index > -1 && index < S) { if (curNode->child_.at(index).get() == nullptr) return std::pair(false,iterator(const_cast(*curNode),-1)); else - return scout_helper(key, curNode->child_.at(index).get()); + return scout_helper(key, curNode->child_.at(index).get(), indexer); } else if (index == -1) { return std::pair(true,iterator(const_cast(*curNode),-1)); } else if (index == -2) { - return std::pair(false,iterator(const_cast(*curNode),-1)); + return std::pair(false,iterator(const_cast(*curNode->parent_),-1)); } // else an invalid index was returned throw std::domain_error("indexer_ returned value outside of [-1," + std::to_string(S) + "]: " + std::to_string(index) + "\n"); @@ -201,8 +219,8 @@ SimpleTrieTemplate::scout_helper(key_type &key, cons template Iterator -SimpleTrieTemplate::insert_helper(Node* &curNode, key_type &key, mapped_type &value) { - int16_t index(indexer_(key,curNode)); +SimpleTrieTemplate::insert_helper(Node* &curNode, key_type &key, mapped_type &value, key_indexer& indexer) { + int16_t index(indexer(key,curNode)); if (index == -1) { curNode->value_ = value; return iterator(*curNode, -1); @@ -210,7 +228,7 @@ SimpleTrieTemplate::insert_helper(Node* &curNode, ke //todo this forces all relative modification/indexing to not allow access to parents else if (index > -1 && index < S) { auto ptr(curNode->child_.at(index).get()); - auto it(insert_helper(ptr, key, value)); + auto it(insert_helper(ptr, key, value, indexer)); if (curNode->child_.at(index).get() == nullptr) { curNode->child_.at(index).reset(ptr); curNode->child_.at(index)->parent_ = curNode; @@ -223,15 +241,14 @@ SimpleTrieTemplate::insert_helper(Node* &curNode, ke template Iterator -SimpleTrieTemplate::insert_helper(Node *&&curNode, key_type &article, mapped_type &value) { - return insert_helper(curNode, article, value); +SimpleTrieTemplate::insert_helper(Node *&&curNode, key_type &article, mapped_type &value, key_indexer& indexer) { + return insert_helper(curNode, article, value, indexer); } template void SimpleTrieTemplate::checkIterPtr_helper(Node* &ptr) { - if (ptr == nullptr) { + if (ptr == nullptr) ptr = begin().get(); - } } #endif // SIMPLETRIETEMPLATE_SIMPLETRIETEMPLATE_CPP \ No newline at end of file