39 #include "NptResults.h" 46 template <
typename K,
typename V>
54 Entry(
const K& key,
const V& value) : m_Key(key), m_Value(value) {}
55 Entry(
const K& key) : m_Key(key), m_Value() {}
58 const K& GetKey()
const {
return m_Key; }
59 const V& GetValue()
const {
return m_Value; }
62 bool operator==(
const Entry& other)
const {
63 return m_Key == other.m_Key && m_Value == other.m_Value;
68 void SetValue(
const V& value) { m_Value = value; }
86 NPT_Result Put(
const K& key,
const V& value);
87 NPT_Result Get(
const K& key, V*& value)
const;
88 bool HasKey(
const K& key)
const {
return GetEntry(key) != NULL; }
89 bool HasValue(
const V& value)
const;
90 NPT_Result Erase(
const K& key);
91 NPT_Cardinal GetEntryCount()
const {
return m_Entries.GetItemCount(); }
96 V& operator[](
const K& key);
106 Entry* GetEntry(
const K& key)
const;
115 template <
typename K,
typename V>
124 template <
typename K,
typename V>
134 template <
typename K,
typename V>
147 template <
typename K,
typename V>
153 if ((*entry)->GetKey() == key) {
165 template <
typename K,
typename V>
169 Entry* entry = GetEntry(key);
172 m_Entries.Add(
new Entry(key, value));
175 entry->SetValue(value);
184 template <
typename K,
typename V>
188 Entry* entry = GetEntry(key);
192 return NPT_ERROR_NO_SUCH_ITEM;
195 value = &entry->m_Value;
203 template <
typename K,
typename V>
209 if (value == (*entry)->m_Value) {
221 template <
typename K,
typename V>
226 if (
this == ©)
return copy;
234 m_Entries.Add(
new Entry((*entry)->GetKey(), (*entry)->GetValue()));
244 template <
typename K,
typename V>
250 if ((*entry)->GetKey() == key) {
254 m_Entries.Erase(entry);
260 return NPT_ERROR_NO_SUCH_ITEM;
266 template <
typename K,
typename V>
271 if (m_Entries.GetItemCount() != other.m_Entries.GetItemCount())
return false;
277 if (NPT_SUCCEEDED(other.Get((*entry)->m_Key, value))) {
279 if (!(*value == (*entry)->m_Value))
return false;
293 template <
typename K,
typename V>
297 return !(*
this == other);
303 template <
typename K,
typename V>
307 Entry* entry = GetEntry(key);
310 entry =
new Entry(key);
311 m_Entries.Add(entry);
314 return entry->m_Value;
320 template <
typename K,
typename V,
typename HF = NPT_Hash<K> >
328 Entry(NPT_UInt32 hash_value,
const K& key,
const V& value) : m_HashValue(hash_value), m_Key(key), m_Value(value) {}
329 Entry(NPT_UInt32 hash_value,
const K& key) : m_HashValue(hash_value), m_Key(key), m_Value() {}
332 const K& GetKey()
const {
return m_Key; }
333 const V& GetValue()
const {
return m_Value; }
334 NPT_UInt32 GetHashValue()
const {
return m_HashValue; }
337 bool operator==(
const Entry& other)
const {
338 return m_HashValue == other.m_HashValue && m_Key == other.m_Key && m_Value == other.m_Value;
343 void SetValue(
const V& value) { m_Value = value; }
346 NPT_UInt32 m_HashValue;
356 Iterator() : m_Entry(NULL), m_Map(NULL) {}
358 Iterator(
const Iterator& copy) : m_Entry(copy.m_Entry), m_Map(copy.m_Map) {}
359 const Entry& operator*()
const {
return **m_Entry; }
361 if (m_Map && m_Entry) {
364 if (m_Entry >= &m_Map->m_Buckets[1<<m_Map->m_BucketCountLog]) {
378 operator bool()
const {
379 return m_Entry != NULL;
381 bool operator==(
const Iterator& other)
const {
382 return m_Map == other.m_Map && m_Entry == other.m_Entry;
384 bool operator!=(
const Iterator& other)
const {
385 return !(*
this == other);
387 void operator=(
const Iterator& other) {
388 m_Entry = other.m_Entry;
410 NPT_Result Put(
const K& key,
const V& value);
411 NPT_Result Get(
const K& key, V*& value)
const;
412 bool HasKey(
const K& key)
const {
return GetEntry(key) != NULL; }
413 bool HasValue(
const V& value)
const;
414 NPT_Result Erase(
const K& key);
415 NPT_Cardinal GetEntryCount()
const {
return m_EntryCount; }
422 template <
typename X>
423 NPT_Result Apply(
const X&
function)
const 425 for (
int i=0; i<(1<<m_BucketCountLog); i++) {
427 function(m_Buckets[i]);
434 V& operator[](
const K& key);
441 Entry* GetEntry(
const K& key, NPT_UInt32* position=NULL)
const;
442 NPT_Result AddEntry(
Entry* entry);
443 void AllocateBuckets(
unsigned int count_log);
444 void AdjustBuckets(NPT_Cardinal entry_count,
bool allow_shrink=
false);
449 NPT_Cardinal m_BucketCountLog;
450 NPT_Cardinal m_EntryCount;
456 template <
typename K,
typename V,
typename HF>
467 template <
typename K,
typename V,
typename HF>
479 template <
typename K,
typename V,
typename HF>
491 template <
typename K,
typename V,
typename HF>
494 for (
int i=0; i<(1<<m_BucketCountLog); i++) {
503 template <
typename K,
typename V,
typename HF>
507 m_Buckets =
new Entry*[1<<count_log];
508 m_BucketCountLog = count_log;
509 for (
int i=0; i<(1<<count_log); i++) {
517 template <
typename K,
typename V,
typename HF>
521 Entry** buckets = NULL;
522 unsigned int bucket_count = 1<<m_BucketCountLog;
523 if (2*entry_count >= bucket_count) {
526 AllocateBuckets(m_BucketCountLog+1);
527 }
else if (allow_shrink && (5*entry_count < bucket_count) && m_BucketCountLog > 4) {
530 AllocateBuckets(m_BucketCountLog-1);
534 for (
unsigned int i=0; i<bucket_count; i++) {
535 if (buckets[i]) AddEntry(buckets[i]);
544 template <
typename K,
typename V,
typename HF>
549 for (
int i=0; i<(1<<m_BucketCountLog); i++) {
563 template <
typename K,
typename V,
typename HF>
567 for (
int i=0; i<(1<<m_BucketCountLog); i++) {
569 return Iterator(&m_Buckets[i],
this);
578 template <
typename K,
typename V,
typename HF>
582 NPT_UInt32 hash_value = m_Hasher(key);
583 NPT_UInt32 mask = (1<<m_BucketCountLog)-1;
584 NPT_UInt32 cursor = hash_value & mask;
585 while (m_Buckets[cursor]) {
586 Entry* entry = m_Buckets[cursor];
587 if (entry->m_HashValue == hash_value &&
588 entry->m_Key == key) {
589 if (position) *position = cursor;
592 cursor = (cursor + 1) & mask;
601 template <
typename K,
typename V,
typename HF>
605 AdjustBuckets(m_EntryCount+1);
607 NPT_UInt32 hash_value = entry->m_HashValue;
608 NPT_UInt32 mask = (1<<m_BucketCountLog)-1;
609 NPT_UInt32 cursor = hash_value & mask;
610 while (m_Buckets[cursor]) {
611 cursor = (cursor + 1) & mask;
613 m_Buckets[cursor] = entry;
622 template <
typename K,
typename V,
typename HF>
626 Entry* entry = GetEntry(key);
629 return AddEntry(
new Entry(m_Hasher(key), key, value));
632 entry->SetValue(value);
641 template <
typename K,
typename V,
typename HF>
645 Entry* entry = GetEntry(key);
649 return NPT_ERROR_NO_SUCH_ITEM;
652 value = &entry->m_Value;
660 template <
typename K,
typename V,
typename HF>
664 for (
int i=0; i<(1<<m_BucketCountLog); i++) {
665 if (m_Buckets[i] && m_Buckets[i]->m_Value == value) {
676 template <
typename K,
typename V,
typename HF>
681 Entry* entry = GetEntry(key, &position);
683 return NPT_ERROR_NO_SUCH_ITEM;
687 m_Buckets[position] = NULL;
692 NPT_UInt32 mask = (1<<m_BucketCountLog)-1;
693 for (NPT_UInt32 cursor = (position+1) & mask; m_Buckets[cursor]; cursor = (cursor + 1) & mask) {
694 NPT_UInt32 target = m_Buckets[cursor]->m_HashValue & mask;
698 if ( (position <= cursor) ?
699 ((position < target) && (target <= cursor)) :
700 ((position < target) || (target <= cursor)) ) {
705 m_Buckets[position] = m_Buckets[cursor];
706 m_Buckets[cursor] = NULL;
713 AdjustBuckets(m_EntryCount,
true);
721 template <
typename K,
typename V,
typename HF>
726 if (
this == ©)
return copy;
732 AdjustBuckets(copy.m_EntryCount);
735 for (
int i=0; i<1<<copy.m_BucketCountLog; i++) {
736 if (copy.m_Buckets[i]) {
737 AddEntry(
new Entry(m_Hasher(copy.m_Buckets[i]->GetKey()),
738 copy.m_Buckets[i]->GetKey(),
739 copy.m_Buckets[i]->GetValue()));
749 template <
typename K,
typename V,
typename HF>
754 if (m_EntryCount != other.m_EntryCount)
return false;
757 for (
int i=0; i<(1<<m_BucketCountLog); i++) {
758 Entry* entry = m_Buckets[i];
759 if (entry == NULL)
continue;
760 Entry* other_entry = other.GetEntry(entry->m_Key);
761 if (other_entry == NULL || !(other_entry->m_Value == entry->m_Value)) {
772 template <
typename K,
typename V,
typename HF>
776 return !(*
this == other);
782 template <
typename K,
typename V,
typename HF>
786 Entry* entry = GetEntry(key);
789 entry =
new Entry(m_Hasher(key), key);
793 return entry->m_Value;
802 void operator()(T* entry)
const {
803 delete entry->GetValue();
807 #endif // _NPT_MAP_H_
Definition: NptCommon.h:45