00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 #ifndef IFPACK_HASHTABLE_H
00053 #define IFPACK_HASHTABLE_H
00054
00055 #include "Ifpack_ConfigDefs.h"
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 template<typename key_type>
00089 class TIfpack_HashTable
00090 {
00091 public:
00093 TIfpack_HashTable(const int n_keys = 1031, const int n_sets = 1)
00094 {
00095 n_keys_ = getRecommendedHashSize(n_keys) ;
00096 n_sets_ = n_sets;
00097 seed_ = (2654435761U);
00098
00099 keys_.reserve(50);
00100 vals_.reserve(50);
00101
00102 keys_.resize(n_sets_);
00103 vals_.resize(n_sets_);
00104
00105 for (int i = 0; i < n_sets_; ++i)
00106 {
00107 keys_[i].resize(n_keys_);
00108 vals_[i].resize(n_keys_);
00109 }
00110
00111 counter_.resize(n_keys_);
00112 for (int i = 0; i < n_keys_; ++i) counter_[i] = 0;
00113 }
00114
00116 inline double get(const key_type key)
00117 {
00118 int hashed_key = doHash(key);
00119
00120 for (int set_ptr = 0; set_ptr < counter_[hashed_key]; ++set_ptr)
00121 {
00122 if (keys_[set_ptr][hashed_key] == key)
00123 return(vals_[set_ptr][hashed_key]);
00124 }
00125
00126 return(0.0);
00127 }
00128
00130 inline void set(const key_type key, const double value,
00131 const bool addToValue = false)
00132 {
00133 int hashed_key = doHash(key);
00134 int& hashed_counter = counter_[hashed_key];
00135
00136 for (int set_ptr = 0; set_ptr < hashed_counter; ++set_ptr)
00137 {
00138 if (keys_[set_ptr][hashed_key] == key)
00139 {
00140 if (addToValue)
00141 vals_[set_ptr][hashed_key] += value;
00142 else
00143 vals_[set_ptr][hashed_key] = value;
00144 return;
00145 }
00146 }
00147
00148 if (hashed_counter < n_sets_)
00149 {
00150 keys_[hashed_counter][hashed_key] = key;
00151 vals_[hashed_counter][hashed_key] = value;
00152 ++hashed_counter;
00153 return;
00154 }
00155
00156 std::vector<key_type> new_key;
00157 std::vector<double> new_val;
00158
00159 keys_.push_back(new_key);
00160 vals_.push_back(new_val);
00161 keys_[n_sets_].resize(n_keys_);
00162 vals_[n_sets_].resize(n_keys_);
00163
00164 keys_[n_sets_][hashed_key] = key;
00165 vals_[n_sets_][hashed_key] = value;
00166 ++hashed_counter;
00167 ++n_sets_;
00168 }
00169
00174 inline void reset()
00175 {
00176 memset(&counter_[0], 0, sizeof(int) * n_keys_);
00177 }
00178
00180 inline int getNumEntries() const
00181 {
00182 int n_entries = 0;
00183 for (int key = 0; key < n_keys_; ++key)
00184 n_entries += counter_[key];
00185 return(n_entries);
00186 }
00187
00189 void arrayify(key_type* key_array, double* val_array)
00190 {
00191 int count = 0;
00192 for (int key = 0; key < n_keys_; ++key)
00193 for (int set_ptr = 0; set_ptr < counter_[key]; ++set_ptr)
00194 {
00195 key_array[count] = keys_[set_ptr][key];
00196 val_array[count] = vals_[set_ptr][key];
00197 ++count;
00198 }
00199 }
00200
00202 void print()
00203 {
00204 cout << "n_keys = " << n_keys_ << endl;
00205 cout << "n_sets = " << n_sets_ << endl;
00206 }
00207
00208 int getRecommendedHashSize (int n)
00209 {
00210
00211
00212
00213
00214 int primes[] = {
00215 3, 7, 13, 23, 53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
00216 49157, 98317, 196613, 393241, 786433, 1572869, 3145739, 6291469,
00217 12582917, 25165842, 50331653, 100663319, 201326611, 402653189,
00218 805306457, 1610612741 } ;
00219 int i, hsize ;
00220
00221
00222
00223
00224
00225 hsize = primes[29] ;
00226 for (i = 6 ; i < 30 ; i++)
00227 {
00228 if (n <= primes[i])
00229 {
00230
00231 hsize = primes[i] ;
00232 break ;
00233 }
00234 }
00235
00236 return hsize ;
00237 }
00238
00239 private:
00241 inline int doHash(const key_type key)
00242 {
00243 return (key % n_keys_);
00244
00245 }
00246
00247 int n_keys_;
00248 int n_sets_;
00249 std::vector<std::vector<double> > vals_;
00250 std::vector<std::vector<key_type> > keys_;
00251 std::vector<int> counter_;
00252 unsigned int seed_;
00253 };
00254
00255 class Ifpack_HashTable : public TIfpack_HashTable<int>
00256 {
00257 public:
00258 Ifpack_HashTable(const int n_keys = 1031, const int n_sets = 1)
00259 : TIfpack_HashTable<int>(n_keys, n_sets)
00260 {
00261 }
00262 };
00263
00264 class Ifpack_HashTable64 : public TIfpack_HashTable<long long>
00265 {
00266 public:
00267 Ifpack_HashTable64(const int n_keys = 1031, const int n_sets = 1)
00268 : TIfpack_HashTable<long long>(n_keys, n_sets)
00269 {
00270 }
00271 };
00272
00273 #endif