forked from xiaoqi-7/knn
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathflatten_hash_map.h
More file actions
137 lines (113 loc) · 3.58 KB
/
Copy pathflatten_hash_map.h
File metadata and controls
137 lines (113 loc) · 3.58 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#ifndef LCTD_FLATTEN_HASH_MAP_H
#define LCTD_FLATTEN_HASH_MAP_H
#include <vector>
namespace koala {
template<typename kType, typename vType>
class _iterator {
};
template<typename V>
class my_openadd_hashmap {
#define LoadfactorInverse 1.5
#define nullele (4294967295U)
public:
//构造函数:初始化自定义类
my_openadd_hashmap() : hash_table(0, std::make_pair(nullele, V())), _size(0) {}
_iterator<unsigned int, V> begin() {
return _iterator<unsigned int, V>();
}
_iterator<unsigned int, V> end() {
return _iterator<unsigned int, V>();
}
unsigned int iterator() {
unsigned int p = 0;
while (p < hash_table.size() && hash_table[p].first == nullele)++p;
return p;
}
unsigned int &next(unsigned int &p) {
++p;
while (p < hash_table.size() && hash_table[p].first == nullele)++p;
return p;
}
bool has_next(unsigned int p) {
return p != hash_table.size();
}
inline V &operator[](unsigned int key) {
int idx = find(key);
if (idx == -1) {
idx = insert(key, V());
}
return hash_table[static_cast<unsigned int>(idx)].second;
}
inline std::pair<unsigned int, V> &get_with_idx(unsigned int i) { return hash_table[i]; }
inline int insert(unsigned int key, V v) {
if ((_size + 1) * LoadfactorInverse > hash_table.size()) {
expand();
}
int idx = put(key, v, hash_table);
if (idx >= 0)_size++;
return idx;
}
inline int insert(std::pair<unsigned int, V> kv) {
return insert(kv.first, kv.second);
}
/*
* if found, return idx of inner data structure
* if not found, return -1
*/
inline int find(unsigned int key) {
if (_size == 0)
return -1;
unsigned int idx = key % hash_table.size();
unsigned int tmpi = (idx + hash_table.size() - 1) % hash_table.size();
while (hash_table[idx].first != nullele && hash_table[idx].first != key && tmpi != idx) {
++idx;
idx = idx == hash_table.size() ? 0 : idx;
}
if (hash_table[idx].first == key) {
return static_cast<int>(idx);
}
return -1;
}
inline void clear() {
hash_table.clear(), hash_table.shrink_to_fit();
//shrink_to_fit(): deque、vector 或 string 退回不需要的内存空间
_size = 0;
}
inline std::vector<unsigned int> &release_data() {
return hash_table;
}
inline unsigned int size() { return _size; }
private:
static inline int put(unsigned int key, V &v, std::vector<std::pair<unsigned int, V>> &table) {
unsigned int idx = key % table.size();
//std::cout<<"ini idx: ("<<idx<<", "<<key<<", "<<v<<")"<<std::endl;
while (table[idx].first != nullele && table[idx].first != key) {
++idx;
idx = idx == table.size() ? 0 : idx;
}
//key 已 valid 存在
//std::cout<<"after while idx: "<<idx<<std::endl;
if (table[idx].first == nullele) {
table[idx] = std::make_pair(key, v);
return static_cast<int>(idx);
//static_cast<type>(x) 把 idx 的类型强制转化成type类型
}
// 是时候进行插入了
return -1;
}
static inline int put(std::pair<unsigned int, V> p, std::vector<std::pair<unsigned int, V>> &table) {
return put(p.first, p.second, table);
}
inline void expand() {
unsigned int _new_size = 0;
if (hash_table.size() == 0)_new_size = 1;
else _new_size = hash_table.size() * 2;
std::vector<std::pair<unsigned int, V>> newtable(_new_size, std::make_pair(nullele, V()));
for (auto &a:hash_table)if (a.first != nullele)put(a, newtable);
swap(newtable, hash_table);
}
std::vector<std::pair<unsigned int, V>> hash_table;
unsigned int _size;
};
}
#endif //LCTD_FLATTEN_HASH_MAP_H