9#include "sparta/utils/Utils.hpp"
38 template <
typename KeyT=u
int64_t,
typename ValT=
void*>
52 typedef std::pair<const KeyT, ValT>
pair_t;
76 typedef typename std::vector<std::unique_ptr<pair_t>>::iterator internal_iter;
82 iterator& operator++() { ++itr_;
return *
this; }
90 bool operator==(
const iterator& rhp)
const {
91 return rhp.itr_ == itr_;
94 bool operator!=(
const iterator& rhp)
const {
95 return rhp.itr_ != itr_;
99 return rhp.itr_ == itr_;
103 return rhp.itr_ != itr_;
106 ValT& operator*() {
return (*itr_)->second; }
107 const ValT& operator*()
const {
return (*itr_)->second; }
109 ValT* operator->() {
return &(*itr_)->second; }
110 const ValT* operator->()
const {
return &(*itr_)->second; }
125 typedef typename std::vector<std::unique_ptr<pair_t>>::const_iterator internal_iter;
140 return rhp.itr_ == itr_;
144 return rhp.itr_ != itr_;
147 bool operator==(
const iterator& rhp)
const {
148 return rhp.itr_ == itr_;
151 bool operator!=(
const iterator& rhp)
const {
152 return rhp.itr_ != itr_;
155 const ValT& operator*()
const {
return (*itr_)->second; }
157 const ValT* operator->()
const {
return &(*itr_)->second; }
180 node_size_(node_size),
182 tier_idx_mask_(~
computeMask<uint64_t>(node_size, tier_shift_))
208 uint64_t
size()
const {
return pairs_.size(); }
227 + (num_nodes_ *
sizeof(
node_t))
228 + (num_nodes_ *
sizeof(
void*) * 0.7)
230 + (pairs_.size() *
sizeof(
typename decltype(tier_shifts_)::value_type))
231 + (
sizeof(tier_shifts_))
232 + (tier_shifts_.size() *
sizeof(
typename decltype(tier_shifts_)::value_type));
242 const_iterator begin()
const {
return pairs_.begin(); }
243 const_iterator end()
const {
return pairs_.end(); }
244 iterator begin() {
return pairs_.begin(); }
245 iterator end() {
return pairs_.end(); }
261 tier_shifts_.clear();
301 return (result->second);
310 return (result->second);
326 uint64_t vidx = k >> tier_shifts_[tidx];
327 if(vidx >= node_size_){
332 vidx = k >> tier_shifts_[tidx];
333 vidx &= tier_idx_mask_;
336 if(vidx >= node.size()){
344 }
while(tidx < num_tiers_);
346 return static_cast<pair_t*
>(v);
356 uint64_t vidx = k >> tier_shifts_[tidx];
357 if(vidx >= node_size_){
362 vidx = k >> tier_shifts_[tidx];
363 vidx &= tier_idx_mask_;
366 if(vidx >= node.size()){
374 }
while(tidx < num_tiers_);
376 return static_cast<const pair_t*
>(v);
390 void allocateRoot_() {
393 && tier_shifts_.size() == 0,
394 "num_nodes_, num_tiers_, and tier_shifts_.size() must be 0 during allocateRoot_");
395 tier_shifts_.push_back(0);
412 ValT& set_(
const KeyT& k,
const ValT n) {
416 uint64_t vidx = k >> tier_shifts_[tidx];
417 if(vidx >= node_size_){
426 vidx = k >> tier_shifts_[tidx];
427 vidx &= tier_idx_mask_;
430 if(vidx >= node.size()){
431 node.resize(vidx+1,
nullptr);
433 void*& vt = node[vidx];
435 if(tidx < num_tiers_ - 1){
444 pairs_.emplace_back(npair);
449 if(tidx == num_tiers_ - 1){
458 }
while(tidx < num_tiers_);
460 return static_cast<pair_t*
>(v)->second;
468 uint64_t new_shift = tier_shifts_[0] + tier_shift_;
469 tier_shifts_.insert(tier_shifts_.begin(), new_shift);
482 void freeNode_(
node_t* n, uint64_t tier=0) {
484 if(tier < num_tiers_ - 1){
485 for(node_t::iterator i = n->begin(); i != n->end(); ++i){
488 freeNode_(child, tier+1);
492 for(node_t::iterator i = n->begin(); i != n->end(); ++i){
504 const uint64_t total_size_;
519 const uint64_t node_size_;
522 uint64_t tier_shift_ = 0;
528 const uint64_t tier_idx_mask_;
534 std::vector<std::unique_ptr<pair_t>> pairs_;
537 std::vector<uint64_t> tier_shifts_;
Set of macros for Sparta assertions. Caught by the framework.
#define sparta_assert(...)
Simple variadic assertion that will throw a sparta_exception if the condition fails.
Exception class for all of Sparta.
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Const for walking contents of this map if const-qualified.
Iterator for walking contents of this map.
N-Tier lookup map for sparse-representation of large memory spaces. This is essentially a M-Tree wher...
std::pair< const KeyT, ValT > pair_t
This map contains mappings between a unique set of keys to values. This type represents that mapping ...
TieredMap(uint64_t node_size=512)
Constructor.
uint64_t getNumTiers() const
Number of tiers used by this map to represent the entire space containing the largest key added....
std::vector< void * > node_t
Node in the map tree. Each node contains up to node_size children, any of which may be.
const pair_t * tryGet(const KeyT &k) const
const-qualified version of tryGet.
const ValT & operator[](const KeyT &k) const
const-qualified index operator
ValT & operator[](const KeyT &k)
Finds a value by its key.
const pair_t * find(const KeyT &k) const
Finds a mapping for key k if one exists in this map.
pair_t * find(const KeyT &k)
Overload for find.
uint64_t getNumNodes() const
Returns the number of nodes allocated within this map.
uint64_t size() const
Number of elements allocated in this map.
uint64_t getEstimatedMemory() const
Returns the estimated memory use by this map in bytes.
void clear()
Clears the map. Frees all mappings and data structures.
pair_t * tryGet(const KeyT &k)
Attempts to get a pair_t associated with the key k without modifying the data structure.
Macros for handling exponential backoff.
T computeMask(T size, T &lsb_pos)
Computes a maks and the lsb-position given a block size. The mask generated can be AND-ed with any nu...
bool isPowerOf2(uint64_t x)
Determines if input is 0 or a power of 2.