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