123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- #ifndef ANDROID_RENDERSCRIPT_MAP_H
- #define ANDROID_RENDERSCRIPT_MAP_H
- #include <stddef.h>
- namespace android {
- namespace renderscript {
- template <class T1, class T2>
- class Pair {
- public:
- Pair() {}
- Pair(T1 f1, T2 f2) : first(f1), second(f2) {}
- T1 first;
- T2 second;
- };
- template <class T1, class T2>
- Pair<T1, T2> make_pair(T1 first, T2 second) {
- return Pair<T1, T2>(first, second);
- }
- #define MAP_LOG_NUM_BUCKET 8
- #define MAP_NUM_BUCKET (1 << MAP_LOG_NUM_BUCKET)
- #define MAP_NUM_BUCKET_MASK (MAP_NUM_BUCKET - 1)
- template <class KeyType, class ValueType>
- class Map {
- private:
- typedef Pair<KeyType, ValueType> MapEntry;
- struct LinkNode {
- MapEntry entry;
- LinkNode* next;
- };
- public:
- Map() : endIterator(MAP_NUM_BUCKET, nullptr, this) {
- for (size_t i = 0; i < MAP_NUM_BUCKET; i++) { bucket[i] = nullptr; }
- }
- ~Map() {
- for (size_t i = 0; i < MAP_NUM_BUCKET; i++) {
- LinkNode* p = bucket[i];
- LinkNode* next;
- while (p != nullptr) {
- next = p->next;
- delete p;
- p = next;
- }
- }
- }
- ValueType& operator[](const KeyType& key) {
- const size_t index = hash(key) & MAP_NUM_BUCKET_MASK;
- LinkNode* node = bucket[index];
- LinkNode* prev = nullptr;
- while (node != nullptr) {
- if (node->entry.first == key) {
- return node->entry.second;
- }
- prev = node;
- node = node->next;
- }
- node = new LinkNode();
- node->entry.first = key;
- node->next = nullptr;
- if (prev == nullptr) {
- bucket[index] = node;
- } else {
- prev->next = node;
- }
- return node->entry.second;
- }
- class iterator {
- friend class Map;
- public:
- iterator& operator++() {
- LinkNode* next;
- next = node->next;
- if (next != nullptr) {
- node = next;
- return *this;
- }
- while (++bucket_index < MAP_NUM_BUCKET) {
- next = map->bucket[bucket_index];
- if (next != nullptr) {
- node = next;
- return *this;
- }
- }
- node = nullptr;
- return *this;
- }
- bool operator==(const iterator& other) const {
- return node == other.node && bucket_index == other.bucket_index &&
- map == other.map;
- }
- bool operator!=(const iterator& other) const {
- return node != other.node || bucket_index != other.bucket_index ||
- map != other.map;
- }
- const MapEntry& operator*() const {
- return node->entry;
- }
- protected:
- iterator(size_t index, LinkNode* n, const Map* m) : bucket_index(index), node(n), map(m) {}
- private:
- size_t bucket_index;
- LinkNode* node;
- const Map* map;
- };
- iterator begin() const {
- for (size_t i = 0; i < MAP_NUM_BUCKET; i++) {
- LinkNode* node = bucket[i];
- if (node != nullptr) {
- return iterator(i, node, this);
- }
- }
- return end();
- }
- const iterator& end() const { return endIterator; }
- iterator begin() { return ((const Map*)this)->begin(); }
- const iterator& end() { return endIterator; }
- iterator find(const KeyType& key) const {
- const size_t index = hash(key) & MAP_NUM_BUCKET_MASK;
- LinkNode* node = bucket[index];
- while (node != nullptr) {
- if (node->entry.first == key) {
- return iterator(index, node, this);
- }
- node = node->next;
- }
- return end();
- }
- private:
- size_t hash(const KeyType& key) const { return ((size_t)key) >> 4; }
- LinkNode* bucket[MAP_NUM_BUCKET];
- const iterator endIterator;
- };
- } // namespace renderscript
- } // namespace android
- #endif // ANDROID_RENDERSCRIPT_MAP_H
|