1 #pragma once 2 3 #include <string> 4 #include <unordered_map> 5 #include <assert.h> 6 #include "node.h" 7 #include "printutils.h" 8 9 /*! 10 Caches string values per node based on the node.index(). 11 The node index guaranteed to be unique per node tree since the index is reset 12 every time a new tree is generated. 13 */ 14 15 class NodeCache 16 { 17 public: NodeCache()18 NodeCache() { } ~NodeCache()19 virtual ~NodeCache() { } 20 contains(const AbstractNode & node)21 bool contains(const AbstractNode &node) const { 22 auto result = this->cache.find(node.index()); 23 return result != this->cache.end() && 24 result->second.second >= 0L && 25 (long)this->rootString.size() >= result->second.second; 26 } 27 28 std::string operator[](const AbstractNode &node) const { 29 // throws std::out_of_range on miss 30 auto indexpair = this->cache.at(node.index()); 31 return rootString.substr(indexpair.first, indexpair.second - indexpair.first); 32 } 33 insertStart(const size_t nodeidx,const long startindex)34 void insertStart(const size_t nodeidx, const long startindex) { 35 assert(this->cache.count(nodeidx) == 0 && "start index inserted twice"); 36 this->cache.emplace(nodeidx, std::make_pair(startindex, -1L)); 37 } 38 insertEnd(const size_t nodeidx,const long endindex)39 void insertEnd(const size_t nodeidx, const long endindex) { 40 // throws std::out_of_range on miss 41 auto indexpair = this->cache.at(nodeidx); 42 assert(indexpair.second == -1L && "end index inserted twice"); 43 this->cache[nodeidx] = std::make_pair(indexpair.first, endindex); 44 #ifdef DEBUG 45 PRINTDB("NodeCache insert {%i,[%d:%d]}", nodeidx % indexpair.first % endindex ); 46 #endif 47 } 48 setRootString(const std::string & rootString)49 void setRootString(const std::string &rootString) { 50 this->rootString = rootString; 51 } 52 clear()53 void clear() { 54 this->cache.clear(); 55 this->rootString = ""; 56 } 57 58 private: 59 std::unordered_map<size_t, std::pair<long,long>> cache; 60 std::string rootString; 61 }; 62