rsMap.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #ifndef ANDROID_RENDERSCRIPT_MAP_H
  2. #define ANDROID_RENDERSCRIPT_MAP_H
  3. #include <stddef.h>
  4. namespace android {
  5. namespace renderscript {
  6. template <class T1, class T2>
  7. class Pair {
  8. public:
  9. Pair() {}
  10. Pair(T1 f1, T2 f2) : first(f1), second(f2) {}
  11. T1 first;
  12. T2 second;
  13. };
  14. template <class T1, class T2>
  15. Pair<T1, T2> make_pair(T1 first, T2 second) {
  16. return Pair<T1, T2>(first, second);
  17. }
  18. #define MAP_LOG_NUM_BUCKET 8
  19. #define MAP_NUM_BUCKET (1 << MAP_LOG_NUM_BUCKET)
  20. #define MAP_NUM_BUCKET_MASK (MAP_NUM_BUCKET - 1)
  21. template <class KeyType, class ValueType>
  22. class Map {
  23. private:
  24. typedef Pair<KeyType, ValueType> MapEntry;
  25. struct LinkNode {
  26. MapEntry entry;
  27. LinkNode* next;
  28. };
  29. public:
  30. Map() : endIterator(MAP_NUM_BUCKET, nullptr, this) {
  31. for (size_t i = 0; i < MAP_NUM_BUCKET; i++) { bucket[i] = nullptr; }
  32. }
  33. ~Map() {
  34. for (size_t i = 0; i < MAP_NUM_BUCKET; i++) {
  35. LinkNode* p = bucket[i];
  36. LinkNode* next;
  37. while (p != nullptr) {
  38. next = p->next;
  39. delete p;
  40. p = next;
  41. }
  42. }
  43. }
  44. ValueType& operator[](const KeyType& key) {
  45. const size_t index = hash(key) & MAP_NUM_BUCKET_MASK;
  46. LinkNode* node = bucket[index];
  47. LinkNode* prev = nullptr;
  48. while (node != nullptr) {
  49. if (node->entry.first == key) {
  50. return node->entry.second;
  51. }
  52. prev = node;
  53. node = node->next;
  54. }
  55. node = new LinkNode();
  56. node->entry.first = key;
  57. node->next = nullptr;
  58. if (prev == nullptr) {
  59. bucket[index] = node;
  60. } else {
  61. prev->next = node;
  62. }
  63. return node->entry.second;
  64. }
  65. class iterator {
  66. friend class Map;
  67. public:
  68. iterator& operator++() {
  69. LinkNode* next;
  70. next = node->next;
  71. if (next != nullptr) {
  72. node = next;
  73. return *this;
  74. }
  75. while (++bucket_index < MAP_NUM_BUCKET) {
  76. next = map->bucket[bucket_index];
  77. if (next != nullptr) {
  78. node = next;
  79. return *this;
  80. }
  81. }
  82. node = nullptr;
  83. return *this;
  84. }
  85. bool operator==(const iterator& other) const {
  86. return node == other.node && bucket_index == other.bucket_index &&
  87. map == other.map;
  88. }
  89. bool operator!=(const iterator& other) const {
  90. return node != other.node || bucket_index != other.bucket_index ||
  91. map != other.map;
  92. }
  93. const MapEntry& operator*() const {
  94. return node->entry;
  95. }
  96. protected:
  97. iterator(size_t index, LinkNode* n, const Map* m) : bucket_index(index), node(n), map(m) {}
  98. private:
  99. size_t bucket_index;
  100. LinkNode* node;
  101. const Map* map;
  102. };
  103. iterator begin() const {
  104. for (size_t i = 0; i < MAP_NUM_BUCKET; i++) {
  105. LinkNode* node = bucket[i];
  106. if (node != nullptr) {
  107. return iterator(i, node, this);
  108. }
  109. }
  110. return end();
  111. }
  112. const iterator& end() const { return endIterator; }
  113. iterator begin() { return ((const Map*)this)->begin(); }
  114. const iterator& end() { return endIterator; }
  115. iterator find(const KeyType& key) const {
  116. const size_t index = hash(key) & MAP_NUM_BUCKET_MASK;
  117. LinkNode* node = bucket[index];
  118. while (node != nullptr) {
  119. if (node->entry.first == key) {
  120. return iterator(index, node, this);
  121. }
  122. node = node->next;
  123. }
  124. return end();
  125. }
  126. private:
  127. size_t hash(const KeyType& key) const { return ((size_t)key) >> 4; }
  128. LinkNode* bucket[MAP_NUM_BUCKET];
  129. const iterator endIterator;
  130. };
  131. } // namespace renderscript
  132. } // namespace android
  133. #endif // ANDROID_RENDERSCRIPT_MAP_H