|
@@ -75,194 +75,77 @@ namespace Spine {
|
|
|
Entry* _entry;
|
|
|
};
|
|
|
|
|
|
- HashMap(size_t capacity = 65535) :
|
|
|
+ HashMap() :
|
|
|
+ _head(NULL),
|
|
|
_hashFunction(),
|
|
|
- _capacity(capacity),
|
|
|
- _header(),
|
|
|
- _trailer(),
|
|
|
- _hashSize(0) {
|
|
|
- _hashTable.reserve(capacity);
|
|
|
- for (int i = 0; i < _capacity; ++i) {
|
|
|
- _hashTable.push_back(Entry());
|
|
|
- }
|
|
|
-
|
|
|
- _header.prev = &_header;
|
|
|
- _header.next = &_trailer;
|
|
|
- _trailer.prev = &_header;
|
|
|
- _trailer.next = &_trailer;
|
|
|
+ _size(0) {
|
|
|
+
|
|
|
}
|
|
|
|
|
|
~HashMap() {
|
|
|
for (Iterator it = begin(); it != end(); ++it) {
|
|
|
delete it._entry;
|
|
|
}
|
|
|
- _hashSize = 0;
|
|
|
}
|
|
|
|
|
|
size_t size() {
|
|
|
- return _hashSize;
|
|
|
+ return _size;
|
|
|
}
|
|
|
|
|
|
Iterator begin() {
|
|
|
- return Iterator(_header.next);
|
|
|
+ return Iterator(_head);
|
|
|
}
|
|
|
|
|
|
Iterator end() {
|
|
|
- return Iterator(&_trailer);
|
|
|
+ return Iterator(NULL);
|
|
|
}
|
|
|
|
|
|
- std::pair<Iterator, bool> insert(const K& key, const V& value) {
|
|
|
- Iterator iter = find(key);
|
|
|
-
|
|
|
- if (iter._entry != &_trailer) {
|
|
|
- return std::make_pair(iter, false);
|
|
|
- }
|
|
|
-
|
|
|
- size_t index = hash(key);
|
|
|
-
|
|
|
- Entry* entry = new (__FILE__, __LINE__) Entry();
|
|
|
- entry->_key = key;
|
|
|
- entry->_value = value;
|
|
|
-
|
|
|
- _hashSize++;
|
|
|
-
|
|
|
- if (_header.next == (&_trailer)) {
|
|
|
- _hashTable[index].next = entry;
|
|
|
- _hashTable[index].prev = entry;
|
|
|
- _header.next = entry;
|
|
|
- entry->prev = &_header;
|
|
|
- entry->next = &_trailer;
|
|
|
- _trailer.prev = entry;
|
|
|
-
|
|
|
- return std::make_pair(Iterator(entry), true);
|
|
|
- }
|
|
|
-
|
|
|
- if (_hashTable[index].next == NULL) {
|
|
|
- _hashTable[index].next = entry;
|
|
|
- _hashTable[index].prev = entry;
|
|
|
- if (index < hash(_header.next->_key)) {
|
|
|
- entry->next = _header.next;
|
|
|
- entry->prev = &_header;
|
|
|
- _header.next->prev = entry;
|
|
|
- _header.next = entry;
|
|
|
- }
|
|
|
- else {
|
|
|
- entry->next = &_trailer;
|
|
|
- entry->prev = _trailer.prev;
|
|
|
- _trailer.prev = entry;
|
|
|
- entry->prev->next = entry;
|
|
|
+ void insert(const K& key, const V& value) {
|
|
|
+ Entry* entry = find(key)._entry;
|
|
|
+ if (entry) {
|
|
|
+ entry->_key = key;
|
|
|
+ entry->_value = value;
|
|
|
+ } else {
|
|
|
+ entry = new (__FILE__, __LINE__) Entry();
|
|
|
+ entry->_key = key;
|
|
|
+ entry->_value = value;
|
|
|
+
|
|
|
+ Entry* oldHead = _head;
|
|
|
+
|
|
|
+ if (oldHead) {
|
|
|
+ _head = entry;
|
|
|
+ oldHead->prev = entry;
|
|
|
+ entry->next = oldHead;
|
|
|
+ } else {
|
|
|
+ _head = entry;
|
|
|
}
|
|
|
-
|
|
|
- return std::make_pair(Iterator(entry), true);
|
|
|
}
|
|
|
-
|
|
|
- if (index == hash(_header.next->_key)) {
|
|
|
- _header.next = entry;
|
|
|
- entry->next = _hashTable[index].next;
|
|
|
- entry->prev = &_header;
|
|
|
- _hashTable[index].next->prev = entry;
|
|
|
- _hashTable[index].next = entry;
|
|
|
- }
|
|
|
- else {
|
|
|
- entry->next = _hashTable[index].next;
|
|
|
- entry->prev = _hashTable[index].next->prev;
|
|
|
- entry->next->prev = entry;
|
|
|
- entry->prev->next = entry;
|
|
|
- _hashTable[index].next = entry;
|
|
|
- }
|
|
|
-
|
|
|
- return std::make_pair(Iterator(entry), true);
|
|
|
}
|
|
|
|
|
|
Iterator find(const K& key) {
|
|
|
- const size_t index = hash(key);
|
|
|
- Iterator iter(_hashTable[index].next);
|
|
|
-
|
|
|
- if (iter._entry != NULL) {
|
|
|
- for ( ; hash(iter._entry->_key) == index ; ++iter) {
|
|
|
- if (iter._entry->_key == key) {
|
|
|
- return iter;
|
|
|
- }
|
|
|
- }
|
|
|
+ for (Iterator it = begin(); it != end(); ++it) {
|
|
|
+ if (it._entry && it.key() == key)
|
|
|
+ return it;
|
|
|
}
|
|
|
-
|
|
|
- return Iterator(&_trailer);
|
|
|
+ return end();
|
|
|
}
|
|
|
|
|
|
Iterator erase(Iterator pos) {
|
|
|
- if (pos._entry != &_header && pos._entry != &_trailer) {
|
|
|
- Entry* next = pos._entry->next;
|
|
|
-
|
|
|
- size_t index = hash(pos._entry->_key);
|
|
|
-
|
|
|
- if (_hashTable[index].next == pos._entry && _hashTable[index].prev == pos._entry) {
|
|
|
- _hashTable[index].next = NULL;
|
|
|
- _hashTable[index].prev = NULL;
|
|
|
-
|
|
|
- if (_header.next == pos._entry) {
|
|
|
- _header.next = pos._entry->next;
|
|
|
- pos._entry->next->prev = &_header;
|
|
|
- }
|
|
|
- else if (_trailer.prev == pos._entry) {
|
|
|
- _trailer.prev = pos._entry->prev;
|
|
|
- pos._entry->prev->next = &_trailer;
|
|
|
- }
|
|
|
- else {
|
|
|
- pos._entry->prev->next = pos._entry->next;
|
|
|
- pos._entry->next->prev = pos._entry->prev;
|
|
|
- }
|
|
|
-
|
|
|
- delete pos._entry;
|
|
|
- }
|
|
|
- else if (_hashTable[index].next == pos._entry) {
|
|
|
- _hashTable[index].next = pos._entry->next;
|
|
|
- if (_header.next == pos._entry) {
|
|
|
- _header.next = pos._entry->next;
|
|
|
- pos._entry->next->prev = &_header;
|
|
|
- }
|
|
|
- else {
|
|
|
- pos._entry->prev->next = pos._entry->next;
|
|
|
- pos._entry->next->prev = pos._entry->prev;
|
|
|
- }
|
|
|
-
|
|
|
- delete pos._entry;
|
|
|
- }
|
|
|
- else if (_hashTable[index].prev == pos._entry) {
|
|
|
- _hashTable[index].prev = pos._entry->prev;
|
|
|
- if (_trailer.prev == pos._entry) {
|
|
|
- _trailer.prev = pos._entry->prev;
|
|
|
- pos._entry->prev->next = &_trailer;
|
|
|
- }
|
|
|
- else {
|
|
|
- pos._entry->prev->next = pos._entry->next;
|
|
|
- pos._entry->next->prev = pos._entry->prev;
|
|
|
- }
|
|
|
-
|
|
|
- delete pos._entry;
|
|
|
- }
|
|
|
- else {
|
|
|
- pos._entry->prev->next = pos._entry->next;
|
|
|
- pos._entry->next->prev = pos._entry->prev;
|
|
|
-
|
|
|
- delete pos._entry;
|
|
|
- }
|
|
|
-
|
|
|
- _hashSize--;
|
|
|
-
|
|
|
- return Iterator(next);
|
|
|
- }
|
|
|
-
|
|
|
- return Iterator(&_trailer);
|
|
|
+ Entry* entry = pos._entry;
|
|
|
+ Entry* prev = entry->prev;
|
|
|
+ Entry* next = entry->next;
|
|
|
+
|
|
|
+ if (prev) prev->next = next;
|
|
|
+ else _head = next;
|
|
|
+ if (next) next->prev = entry->prev;
|
|
|
+
|
|
|
+ delete entry;
|
|
|
+ return Iterator(next);
|
|
|
}
|
|
|
|
|
|
V operator[](const K& key) {
|
|
|
Iterator iter = find(key);
|
|
|
-
|
|
|
- if (iter._entry != _trailer) {
|
|
|
- return iter._entry->_value;
|
|
|
- }
|
|
|
-
|
|
|
- return V();
|
|
|
+ return iter;
|
|
|
}
|
|
|
|
|
|
private:
|
|
@@ -272,18 +155,13 @@ namespace Spine {
|
|
|
V _value;
|
|
|
Entry* next;
|
|
|
Entry* prev;
|
|
|
+
|
|
|
+ Entry () : next(NULL), prev(NULL) {}
|
|
|
};
|
|
|
|
|
|
const H _hashFunction;
|
|
|
- const size_t _capacity;
|
|
|
- Vector<Entry> _hashTable;
|
|
|
- Entry _header;
|
|
|
- Entry _trailer;
|
|
|
- size_t _hashSize;
|
|
|
-
|
|
|
- size_t hash(const K& key) {
|
|
|
- return _hashFunction(key) % _capacity;
|
|
|
- }
|
|
|
+ Entry* _head;
|
|
|
+ size_t _size;
|
|
|
};
|
|
|
}
|
|
|
|