You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

limitedmap.h 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. // Copyright (c) 2012 The Bitcoin developers
  2. // Distributed under the MIT/X11 software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #ifndef BITCOIN_LIMITEDMAP_H
  5. #define BITCOIN_LIMITEDMAP_H
  6. #include <assert.h> // TODO: remove
  7. #include <map>
  8. /** STL-like map container that only keeps the N elements with the highest value. */
  9. template <typename K, typename V> class limitedmap
  10. {
  11. public:
  12. typedef K key_type;
  13. typedef V mapped_type;
  14. typedef std::pair<const key_type, mapped_type> value_type;
  15. typedef typename std::map<K, V>::const_iterator const_iterator;
  16. typedef typename std::map<K, V>::size_type size_type;
  17. protected:
  18. std::map<K, V> map;
  19. typedef typename std::map<K, V>::iterator iterator;
  20. std::multimap<V, iterator> rmap;
  21. typedef typename std::multimap<V, iterator>::iterator rmap_iterator;
  22. size_type nMaxSize;
  23. public:
  24. limitedmap(size_type nMaxSizeIn = 0) { nMaxSize = nMaxSizeIn; }
  25. const_iterator begin() const { return map.begin(); }
  26. const_iterator end() const { return map.end(); }
  27. size_type size() const { return map.size(); }
  28. bool empty() const { return map.empty(); }
  29. const_iterator find(const key_type& k) const { return map.find(k); }
  30. size_type count(const key_type& k) const { return map.count(k); }
  31. void insert(const value_type& x)
  32. {
  33. std::pair<iterator, bool> ret = map.insert(x);
  34. if (ret.second)
  35. {
  36. if (nMaxSize && map.size() == nMaxSize)
  37. {
  38. map.erase(rmap.begin()->second);
  39. rmap.erase(rmap.begin());
  40. }
  41. rmap.insert(make_pair(x.second, ret.first));
  42. }
  43. return;
  44. }
  45. void erase(const key_type& k)
  46. {
  47. iterator itTarget = map.find(k);
  48. if (itTarget == map.end())
  49. return;
  50. std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second);
  51. for (rmap_iterator it = itPair.first; it != itPair.second; ++it)
  52. if (it->second == itTarget)
  53. {
  54. rmap.erase(it);
  55. map.erase(itTarget);
  56. return;
  57. }
  58. // Shouldn't ever get here
  59. assert(0); //TODO remove me
  60. map.erase(itTarget);
  61. }
  62. void update(const_iterator itIn, const mapped_type& v)
  63. {
  64. //TODO: When we switch to C++11, use map.erase(itIn, itIn) to get the non-const iterator
  65. iterator itTarget = map.find(itIn->first);
  66. if (itTarget == map.end())
  67. return;
  68. std::pair<rmap_iterator, rmap_iterator> itPair = rmap.equal_range(itTarget->second);
  69. for (rmap_iterator it = itPair.first; it != itPair.second; ++it)
  70. if (it->second == itTarget)
  71. {
  72. rmap.erase(it);
  73. itTarget->second = v;
  74. rmap.insert(make_pair(v, itTarget));
  75. return;
  76. }
  77. // Shouldn't ever get here
  78. assert(0); //TODO remove me
  79. itTarget->second = v;
  80. rmap.insert(make_pair(v, itTarget));
  81. }
  82. size_type max_size() const { return nMaxSize; }
  83. size_type max_size(size_type s)
  84. {
  85. if (s)
  86. while (map.size() > s)
  87. {
  88. map.erase(rmap.begin()->second);
  89. rmap.erase(rmap.begin());
  90. }
  91. nMaxSize = s;
  92. return nMaxSize;
  93. }
  94. };
  95. #endif