00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef immutable_hash_map_h
00011 #define immutable_hash_map_h
00012
00013
00014
00015 #include <inttypes.h>
00016 #include <math.h>
00017 #include <vector>
00018
00019 template<typename key_type, typename value_type>
00020 class immutable_hash_map
00021 {
00022 public:
00023 std::vector<key_type> _keys;
00024 std::vector<value_type> _values;
00025 int _size;
00026 int _mask;
00027
00028 immutable_hash_map(key_type* keys, value_type* values, int size)
00029 : _size(size)
00030 {
00031 if (size <= 0) {
00032 _keys.resize(1,"");
00033 _values.resize(1);
00034 _mask = 0;
00035 return;
00036 }
00037
00038
00039 int table_size = 1<<int(ceil(log(size * 2) * (1/M_LN2)));
00040 _mask = table_size-1;
00041
00042 _keys.resize(table_size);
00043 _values.resize(table_size);
00044
00045 key_type* kp = keys, *end = kp + size;
00046 value_type* vp = values;
00047 while (kp != end) {
00048 int pos = find(*kp);
00049 _keys[pos] = *kp++;
00050 _values[pos] = *vp++;
00051 }
00052 }
00053
00054 const value_type& operator[] (const key_type& key) const
00055 {
00056 return _values[find(key)];
00057 }
00058
00059 int size() const { return _size; }
00060
00061 private:
00062 int find(const key_type& key) const
00063 {
00064 uint32_t hash = intptr_t(key) ^ (intptr_t(key)>>32);
00065
00066 hash = ~hash + (hash << 15);
00067 hash = hash ^ (hash >> 12);
00068 hash = hash + (hash << 2);
00069 hash = hash ^ (hash >> 4);
00070 hash = hash * 2057;
00071 hash = hash ^ (hash >> 16);
00072 while (1) {
00073 int pos = hash & _mask;
00074 const key_type& k = _keys[pos];
00075 if (k == key || !k) return pos;
00076 hash++;
00077 }
00078 }
00079 };
00080
00081 #endif