forked from OctaForge/libostd
hashtble rehash support
This commit is contained in:
parent
e2d8283eb7
commit
4715e09f35
|
@ -136,7 +136,7 @@ namespace detail {
|
||||||
|
|
||||||
~Hashtable() {
|
~Hashtable() {
|
||||||
octa::allocator_deallocate(get_cpalloc(), p_data.first(), p_size);
|
octa::allocator_deallocate(get_cpalloc(), p_data.first(), p_size);
|
||||||
delete_chunks();
|
delete_chunks(p_chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool empty() const { return p_len == 0; }
|
bool empty() const { return p_len == 0; }
|
||||||
|
@ -190,11 +190,11 @@ namespace detail {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void delete_chunks() {
|
void delete_chunks(Chunk *chunks) {
|
||||||
for (Chunk *nc; p_chunks; p_chunks = nc) {
|
for (Chunk *nc; chunks; chunks = nc) {
|
||||||
nc = p_chunks->next;
|
nc = chunks->next;
|
||||||
octa::allocator_destroy(get_challoc(), p_chunks);
|
octa::allocator_destroy(get_challoc(), chunks);
|
||||||
octa::allocator_deallocate(get_challoc(), p_chunks, 1);
|
octa::allocator_deallocate(get_challoc(), chunks, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ namespace detail {
|
||||||
memset(p_data.first(), 0, p_size * sizeof(Chain *));
|
memset(p_data.first(), 0, p_size * sizeof(Chain *));
|
||||||
p_len = 0;
|
p_len = 0;
|
||||||
p_unused = nullptr;
|
p_unused = nullptr;
|
||||||
delete_chunks();
|
delete_chunks(p_chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename U>
|
template<typename U>
|
||||||
|
@ -230,13 +230,45 @@ namespace detail {
|
||||||
return (insert(h, key) = val);
|
return (insert(h, key) = val);
|
||||||
}
|
}
|
||||||
|
|
||||||
float load_factor() const { return p_len / float(p_size); }
|
float load_factor() const { return float(p_len) / p_size; }
|
||||||
float max_load_factor() const { return p_maxlf; }
|
float max_load_factor() const { return p_maxlf; }
|
||||||
void max_load_factor(float lf) { p_maxlf = lf; }
|
void max_load_factor(float lf) { p_maxlf = lf; }
|
||||||
|
|
||||||
octa::Size bucket_count() const { return p_size; }
|
octa::Size bucket_count() const { return p_size; }
|
||||||
octa::Size max_bucket_count() const { return Size(~0) / sizeof(Chain); }
|
octa::Size max_bucket_count() const { return Size(~0) / sizeof(Chain); }
|
||||||
|
|
||||||
|
void rehash(octa::Size count) {
|
||||||
|
count = octa::max(count, octa::Size(p_len / max_load_factor()));
|
||||||
|
|
||||||
|
Chain **och = p_data.first();
|
||||||
|
Chain **nch = octa::allocator_allocate(get_cpalloc(), count);
|
||||||
|
memset(nch, 0, count * sizeof(Chain *));
|
||||||
|
p_data.first() = nch;
|
||||||
|
|
||||||
|
Chunk *chunks = p_chunks;
|
||||||
|
octa::Size osize = p_size;
|
||||||
|
|
||||||
|
p_chunks = nullptr;
|
||||||
|
p_unused = nullptr;
|
||||||
|
p_size = count;
|
||||||
|
p_len = 0;
|
||||||
|
|
||||||
|
for (octa::Size i = 0; i < osize; ++i) {
|
||||||
|
for (Chain *oc = och[i]; oc; oc = oc->next) {
|
||||||
|
octa::Size h = get_hash()(B::get_key(oc->value)) & (count - 1);
|
||||||
|
Chain *nc = insert(h);
|
||||||
|
B::swap_elem(oc->value, nc->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
octa::allocator_deallocate(get_cpalloc(), och, osize);
|
||||||
|
delete_chunks(chunks);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(octa::Size count) {
|
||||||
|
rehash(octa::Size(ceil(count / max_load_factor())));
|
||||||
|
}
|
||||||
|
|
||||||
Range each() {
|
Range each() {
|
||||||
return Range(p_data.first(), bucket_count());
|
return Range(p_data.first(), bucket_count());
|
||||||
}
|
}
|
||||||
|
|
12
octa/map.h
12
octa/map.h
|
@ -30,6 +30,10 @@ namespace detail {
|
||||||
e.first.~K();
|
e.first.~K();
|
||||||
new ((K *)&e.first) K(octa::forward<U>(key));
|
new ((K *)&e.first) K(octa::forward<U>(key));
|
||||||
}
|
}
|
||||||
|
static inline void swap_elem(Element &a, Element &b) {
|
||||||
|
octa::swap(*((K *)&a.first), *((K *)&b.first));
|
||||||
|
octa::swap(*((T *)&a.second), *((T *)&b.second));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,6 +109,14 @@ public:
|
||||||
float max_load_factor() const { return p_table.max_load_factor(); }
|
float max_load_factor() const { return p_table.max_load_factor(); }
|
||||||
void max_load_factor(float lf) { p_table.max_load_factor(lf); }
|
void max_load_factor(float lf) { p_table.max_load_factor(lf); }
|
||||||
|
|
||||||
|
void rehash(octa::Size count) {
|
||||||
|
p_table.rehash(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reserve(octa::Size count) {
|
||||||
|
p_table.reserve(count);
|
||||||
|
}
|
||||||
|
|
||||||
Range each() { return p_table.each(); }
|
Range each() { return p_table.each(); }
|
||||||
ConstRange each() const { return p_table.each(); }
|
ConstRange each() const { return p_table.each(); }
|
||||||
ConstRange ceach() const { return p_table.ceach(); }
|
ConstRange ceach() const { return p_table.ceach(); }
|
||||||
|
|
|
@ -307,7 +307,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(StringBase &v) {
|
void swap(StringBase &v) {
|
||||||
p_buf.swap(v);
|
p_buf.swap(v.p_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
Size to_hash() const {
|
Size to_hash() const {
|
||||||
|
|
Loading…
Reference in a new issue