Line data Source code
1 : /* 2 : * Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. 3 : */ 4 : 5 : #ifndef ctrlplane_index_map_h 6 : #define ctrlplane_index_map_h 7 : 8 : #include <cassert> 9 : #include <map> 10 : #include <vector> 11 : #include "base/bitset.h" 12 : #include "base/util.h" 13 : 14 : // 15 : // An key, value map associated with an index. 16 : // 17 : template <typename KeyType, typename ValueType, 18 : typename BitsetType = BitSet> 19 : class IndexMap { 20 : public: 21 : typedef std::vector<ValueType *> VectorType; 22 : typedef std::map<KeyType, ValueType *> MapType; 23 : typedef typename MapType::iterator iterator; 24 : typedef typename MapType::const_iterator const_iterator; 25 : 26 120265 : IndexMap() { } 27 120265 : ~IndexMap() { 28 120265 : STLDeleteValues(&values_); 29 120265 : } 30 : 31 4317049 : ValueType *At(int index) const { 32 4317049 : return values_[index]; 33 : } 34 5038798 : ValueType *Find(const KeyType &key) const { 35 5038798 : typename MapType::const_iterator loc = map_.find(key); 36 5038517 : if (loc != map_.end()) { 37 4614714 : return loc->second; 38 : } 39 423762 : return NULL; 40 : } 41 : 42 8049 : void ReserveBit(int index) { 43 8049 : if (bits_.test(index)) 44 0 : assert(!values_[index]); 45 8049 : bits_.set(index); 46 8049 : values_.resize(values_.size() + 1); 47 8049 : } 48 : 49 : // Allocate a new index associated with the new key. 50 363350 : size_t Insert(const KeyType &key, ValueType *value, int index = -1) { 51 : std::pair<typename MapType::iterator, bool> result = 52 363350 : map_.insert(std::make_pair(key, value)); 53 363350 : if (!result.second) { 54 0 : return -1; 55 : } 56 363350 : size_t bit = index; 57 363350 : if (index == -1) 58 355320 : bit = bits_.find_first_clear(); 59 363350 : if (bit >= values_.size()) { 60 342157 : assert(bit == values_.size()); 61 342157 : values_.push_back(value); 62 : } else { 63 21193 : values_[bit] = value; 64 : } 65 363350 : bits_.set(bit); 66 363350 : return bit; 67 : } 68 : 69 323075 : void Remove(const KeyType &key, int index, bool clear_bit = true) { 70 323075 : typename MapType::iterator loc = map_.find(key); 71 323075 : assert(loc != map_.end()); 72 323075 : assert(loc->second == values_[index]); 73 323075 : map_.erase(loc); 74 323075 : if (clear_bit) 75 312689 : ResetBit(index); 76 323075 : } 77 : 78 363227 : void ResetBit(int index) { 79 363227 : bits_.reset(index); 80 363227 : ValueType *value = values_[index]; 81 363227 : values_[index] = NULL; 82 363227 : delete value; 83 713283 : for (int64_t i = values_.size() - 1; i >= 0; i--) { 84 635705 : if (values_[i] != NULL) { 85 285649 : break; 86 : } 87 350056 : values_.pop_back(); 88 : } 89 363227 : } 90 : 91 831396 : ValueType *Locate(const KeyType &key) { 92 831396 : ValueType *value = Find(key); 93 831396 : if (value == NULL) { 94 312623 : value = new ValueType(key); 95 312623 : value->set_index(Insert(key, value)); 96 : } 97 831396 : return value; 98 : } 99 : 100 25599 : size_t size() const { return values_.size(); } 101 76 : size_t count() const { return map_.size(); } 102 170384 : bool empty() const { return map_.empty(); } 103 : 104 8048 : void clear() { 105 8048 : bits_.clear(); 106 8048 : STLDeleteValues(&values_); 107 8048 : map_.clear(); 108 8048 : } 109 : 110 564 : const BitsetType &bits() const { return bits_; } 111 : 112 : iterator begin() { return map_.begin(); } 113 : iterator end() { return map_.end(); } 114 : iterator lower_bound(const KeyType &key) { 115 : return map_.lower_bound(key); 116 : } 117 : const_iterator cbegin() { return map_.begin(); } 118 : const_iterator cend() { return map_.end(); } 119 : const_iterator clower_bound(const KeyType &key) { 120 : return map_.lower_bound(key); 121 : } 122 : 123 : private: 124 : BitsetType bits_; 125 : VectorType values_; 126 : MapType map_; 127 : DISALLOW_COPY_AND_ASSIGN(IndexMap); 128 : }; 129 : 130 : #endif