Skip to content

Commit b0a04cf

Browse files
author
Jinglei Ren
committed
Moves depended slib hashtable to local.
1 parent 06f1a72 commit b0a04cf

File tree

12 files changed

+869
-10
lines changed

12 files changed

+869
-10
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,8 @@
3131
.project
3232
.cproject
3333
.settings/
34+
35+
*.result
36+
*.log
37+
*.data
38+
*.output

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CC=g++
1+
CC=g++-4.9
22
CFLAGS=-std=c++11 -g -Wall -pthread -I./
33
LDFLAGS= -L/home/jinglei/Projects/sitevm_dune-master/bin -L/home/jinglei/Projects/dune/libdune -lpthread -ltbb -lsitevm -ldune
44
SUBDIRS=core db

core/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
CC=g++
1+
CC=g++-4.9
22
CFLAGS=-std=c++11 -c -g -Wall
33
SOURCES=$(wildcard *.cc)
44
OBJECTS=$(SOURCES:.cc=.o)

db/Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
CC=g++
2-
CFLAGS=-std=c++11 -c -g -Wall
3-
INCLUDES=-I../ -I/home/jinglei/Projects/sitevm_dune-master -I/home/jinglei/Projects/vm-persistence
1+
CC=g++-4.9
2+
CFLAGS=-std=c++11 -c -g -Wall -fgnu-tm
3+
INCLUDES=-I../ -I/home/jinglei/Projects/sitevm_dune-master
44
SOURCES=$(wildcard *.cc)
55
OBJECTS=$(SOURCES:.cc=.o)
66

db/svm_slib_db.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include <vector>
1212
#include "sitevm/sitevm.h"
13-
#include "slib/mem_alloc.h"
13+
#include "lib/mem_alloc.h"
1414
#include "lib/slib_hashtable.h"
1515
#include "lib/trans_def.h"
1616

db/svm_stl_db.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
#include <vector>
1212
#include "sitevm/sitevm.h"
13-
#include "slib/mem_alloc.h"
13+
#include "lib/mem_alloc.h"
1414
#include "lib/svm_stl_hashtable.h"
1515
#include "lib/trans_def.h"
1616

lib/hashtable.h

Lines changed: 264 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,264 @@
1+
//
2+
// hashtable.h
3+
// vm_persistence
4+
//
5+
// Created by Jinglei Ren on 12/24/14.
6+
// Copyright (c) 2014 Jinglei Ren <jinglei@ren.systems>.
7+
//
8+
9+
#ifndef VM_PERSISTENCE_SLIB_HASHTABLE_H_
10+
#define VM_PERSISTENCE_SLIB_HASHTABLE_H_
11+
12+
#include <cstdint>
13+
#include <cassert>
14+
#include "lib/list.h"
15+
#include "lib/mem_alloc.h"
16+
17+
namespace slib {
18+
19+
template<typename T>
20+
struct HashEqual {
21+
virtual uint64_t hash(const T &key) const {
22+
std::hash<T> hasher;
23+
return hasher(key);
24+
}
25+
26+
virtual bool equal(const T &x, const T &y) const {
27+
std::equal_to<T> equal;
28+
return equal(x, y);
29+
}
30+
31+
virtual ~HashEqual() { }
32+
};
33+
34+
struct hlist_bucket {
35+
std::size_t size;
36+
struct hlist_head head;
37+
};
38+
39+
template <typename K, typename V>
40+
struct hlist_pair {
41+
K key;
42+
V value;
43+
hlist_node node;
44+
45+
hlist_pair(const K &k, const V &v) : key(k), value(v) {
46+
INIT_HLIST_NODE(&node);
47+
}
48+
};
49+
50+
template <typename K, typename V, class HashEqual, class Alloc>
51+
class hashtable {
52+
public:
53+
hashtable(std::size_t num_buckets = 11, std::size_t local_load_factor = 4);
54+
size_t local_load_factor() const { return local_load_factor_; }
55+
void set_local_load_factor(std::size_t f) { local_load_factor_ = f; }
56+
std::size_t bucket_count() const { return bucket_count_; }
57+
58+
bool find(const K &key, V &value) const;
59+
bool update(const K &key, V &value);
60+
bool insert(const K &key, const V &value);
61+
bool erase(const K &key, std::pair<K, V> &erased);
62+
std::vector<std::pair<K, V>> entries(const K *key = NULL,
63+
std::size_t n = -1) const;
64+
std::size_t clear();
65+
void rehash(std::size_t buckets);
66+
67+
std::size_t size() const;
68+
std::size_t bucket_size(size_t i) const { return buckets_[i].size; }
69+
float load_factor() const;
70+
71+
~hashtable();
72+
73+
private:
74+
hlist_bucket *get_bucket(const K &key) const {
75+
return buckets_ + hash_equal_.hash(key) % bucket_count_;
76+
}
77+
78+
std::size_t local_load_factor_;
79+
hlist_bucket *buckets_;
80+
std::size_t bucket_count_;
81+
HashEqual hash_equal_;
82+
};
83+
84+
// Accessory functions
85+
86+
template <class Alloc>
87+
inline hlist_bucket *new_buckets(std::size_t n) {
88+
hlist_bucket *bkts = (hlist_bucket *)Alloc::Malloc(n * sizeof(hlist_bucket));
89+
for (std::size_t i = 0; i < n; ++i) {
90+
bkts[i].size = 0;
91+
INIT_HLIST_HEAD(&bkts[i].head);
92+
}
93+
return bkts;
94+
}
95+
96+
inline std::size_t size_sum(const hlist_bucket *bkts, std::size_t n) {
97+
std::size_t count = 0;
98+
for (std::size_t i = 0; i < n; ++i) {
99+
count += bkts[i].size;
100+
}
101+
return count;
102+
}
103+
104+
template <typename K, typename V, class HashEqual, class Alloc>
105+
hlist_pair<K, V> *find_in(const hlist_bucket *bkt, const K &key,
106+
const HashEqual &hash_equal = HashEqual()) {
107+
hlist_node *node;
108+
hlist_for_each(node, &bkt->head) {
109+
hlist_pair<K, V> *pair = container_of(node, &hlist_pair<K, V>::node);
110+
if (hash_equal.equal(pair->key, key)) {
111+
return pair;
112+
}
113+
}
114+
return NULL;
115+
}
116+
117+
template <typename K, typename V>
118+
void insert_to(hlist_bucket *bkt, hlist_pair<K, V> *pair) {
119+
hlist_add_head(&pair->node, &bkt->head);
120+
++bkt->size;
121+
}
122+
123+
template <typename K, typename V, class Alloc>
124+
void erase_from(hlist_bucket *bkt, hlist_pair<K, V> *pair) {
125+
hlist_del(&pair->node);
126+
Alloc::Delete(pair);
127+
--bkt->size;
128+
assert((bool)bkt->size != hlist_empty(&bkt->head));
129+
}
130+
131+
template <typename K, typename V, class Alloc>
132+
std::size_t clear_all(hlist_bucket *bkts, std::size_t n) {
133+
std::size_t num = 0;
134+
for (std::size_t i = 0; i < n; ++i) {
135+
hlist_node *pos, *next;
136+
hlist_for_each_safe(pos, next, &bkts[i].head) {
137+
hlist_pair<K, V> *pair = container_of(pos, &hlist_pair<K, V>::node);
138+
erase_from<K, V, Alloc>(bkts + i, pair);
139+
++num;
140+
}
141+
assert(!bkts[i].size && hlist_empty(&bkts[i].head));
142+
}
143+
return num;
144+
}
145+
146+
// Implementation of hashtable
147+
148+
template <typename K, typename V, class HashEqual, class Alloc>
149+
hashtable<K, V, HashEqual, Alloc>::hashtable(std::size_t n, std::size_t f) {
150+
bucket_count_ = n;
151+
buckets_ = new_buckets<Alloc>(bucket_count_);
152+
local_load_factor_ = f;
153+
}
154+
155+
template <typename K, typename V, class HashEqual, class Alloc>
156+
bool hashtable<K, V, HashEqual, Alloc>::find(const K &key, V &value) const {
157+
hlist_bucket *bkt = get_bucket(key);
158+
hlist_pair<K, V> *pair = find_in<K, V, HashEqual, Alloc>(bkt, key);
159+
if (!pair) return false;
160+
value = pair->value;
161+
return true;
162+
}
163+
164+
template <typename K, typename V, class HashEqual, class Alloc>
165+
bool hashtable<K, V, HashEqual, Alloc>::update(const K &key, V &value) {
166+
hlist_bucket *bkt = get_bucket(key);
167+
hlist_pair<K, V> *pair = find_in<K, V, HashEqual, Alloc>(bkt, key);
168+
if (!pair) return false;
169+
V old = pair->value;
170+
pair->value = value;
171+
value = old;
172+
return true;
173+
}
174+
175+
template <typename K, typename V, class HashEqual, class Alloc>
176+
bool hashtable<K, V, HashEqual, Alloc>::insert(const K &key, const V &value) {
177+
hlist_bucket *bkt = get_bucket(key);
178+
hlist_pair<K, V> *pair = find_in<K, V, HashEqual, Alloc>(bkt, key);
179+
if (pair) return false;
180+
pair = Alloc::template New<hlist_pair<K, V>>(key, value);
181+
insert_to(bkt, pair);
182+
183+
if (bkt->size >= local_load_factor_) {
184+
rehash((bucket_count_ << 1) + 1);
185+
}
186+
return true;
187+
}
188+
189+
template <typename K, typename V, class HashEqual, class Alloc>
190+
bool hashtable<K, V, HashEqual, Alloc>::erase(const K &key, std::pair<K, V> &erased) {
191+
hlist_bucket *bkt = get_bucket(key);
192+
hlist_pair<K, V> *pair = find_in<K, V, HashEqual, Alloc>(bkt, key);
193+
if (!pair) return false;
194+
erased.first = pair->key;
195+
erased.second = pair->value;
196+
erase_from<K, V, Alloc>(bkt, pair);
197+
return true;
198+
}
199+
200+
template <typename K, typename V, class HashEqual, class Alloc>
201+
std::vector<std::pair<K, V>> hashtable<K, V, HashEqual, Alloc>::entries(
202+
const K *key, std::size_t num) const {
203+
std::vector<std::pair<K, V>> pairs;
204+
hlist_bucket *bkt = key ? get_bucket(*key) : buckets_;
205+
hlist_pair<K, V> *pos = key ? find_in<K, V, HashEqual, Alloc>(bkt, *key) :
206+
container_of(bkt->head.first, &hlist_pair<K, V>::node);
207+
if (!pos) return pairs;
208+
209+
hlist_bucket *bkt_end = buckets_ + bucket_count_;
210+
hlist_node *node = &pos->node;
211+
for (; bkt < bkt_end; ++bkt) {
212+
if (!node) node = bkt->head.first;
213+
for (; node; node = node->next) {
214+
hlist_pair<K, V> *pair = container_of(node, &hlist_pair<K, V>::node);
215+
pairs.push_back(std::make_pair(pair->key, pair->value));
216+
if (pairs.size() == num) return pairs;
217+
}
218+
}
219+
return pairs;
220+
}
221+
222+
template <typename K, typename V, class HashEqual, class Alloc>
223+
std::size_t hashtable<K, V, HashEqual, Alloc>::clear() {
224+
return clear_all<K, V, Alloc>(buckets_, bucket_count_);
225+
}
226+
227+
template <typename K, typename V, class HashEqual, class Alloc>
228+
hashtable<K, V, HashEqual, Alloc>::~hashtable() {
229+
clear_all<K, V, Alloc>(buckets_, bucket_count_);
230+
Alloc::Free(buckets_, sizeof(hlist_bucket) * bucket_count_);
231+
}
232+
233+
template <typename K, typename V, class HashEqual, class Alloc>
234+
void hashtable<K, V, HashEqual, Alloc>::rehash(std::size_t n) {
235+
hlist_bucket *bkts = new_buckets<Alloc>(n);
236+
std::size_t num = 0;
237+
for (std::size_t i = 0; i < bucket_count_; ++i) {
238+
hlist_node *pos, *next;
239+
hlist_for_each_safe(pos, next, &buckets_[i].head) {
240+
hlist_pair<K, V> *pair = container_of(pos, &hlist_pair<K, V>::node);
241+
std::size_t j = hash_equal_.hash(pair->key) % n;
242+
insert_to(bkts + j, pair);
243+
++num;
244+
}
245+
}
246+
Alloc::Free(buckets_, sizeof(hlist_bucket) * bucket_count_);
247+
buckets_ = bkts;
248+
bucket_count_ = n;
249+
}
250+
251+
template <typename K, typename V, class HashEqual, class Alloc>
252+
std::size_t hashtable<K, V, HashEqual, Alloc>::size() const {
253+
return size_sum(buckets_, bucket_count_);
254+
}
255+
256+
template <typename K, typename V, class HashEqual, class Alloc>
257+
float hashtable<K, V, HashEqual, Alloc>::load_factor() const {
258+
return size() / (float)bucket_count_;
259+
}
260+
261+
} // namespace slib
262+
263+
#endif // VM_PERSISTENCE_SLIB_HASHTABLE_H_
264+

0 commit comments

Comments
 (0)