forked from OctaForge/libostd
hash table copy/move ctor support
This commit is contained in:
parent
3b65b0cb99
commit
e0a498806a
|
@ -151,6 +151,7 @@ namespace detail {
|
|||
const C &get_eq() const { return p_data.second().second().second(); }
|
||||
|
||||
A &get_alloc() { return p_data.second().first().first(); }
|
||||
const A &get_alloc() const { return p_data.second().first().first(); }
|
||||
CPA &get_cpalloc() { return p_data.second().first().second().first(); }
|
||||
CHA &get_challoc() { return p_data.second().first().second().second(); }
|
||||
|
||||
|
@ -159,12 +160,73 @@ namespace detail {
|
|||
p_data(nullptr, FAPair(AllocPair(alloc, CoreAllocPair(alloc, alloc)),
|
||||
FuncPair(hf, eqf))),
|
||||
p_maxlf(1.0f) {
|
||||
if (!size) return;
|
||||
p_data.first() = octa::allocator_allocate(get_cpalloc(), size);
|
||||
memset(p_data.first(), 0, size * sizeof(Chain *));
|
||||
}
|
||||
|
||||
Hashtable(const Hashtable &ht, const A &alloc): p_size(ht.p_size),
|
||||
p_len(0), p_chunks(nullptr), p_unused(nullptr),
|
||||
p_data(nullptr, FAPair(AllocPair(alloc, CoreAllocPair(alloc, alloc)),
|
||||
FuncPair(ht.get_hash(), ht.get_eq()))),
|
||||
p_maxlf(ht.p_maxlf) {
|
||||
if (!p_size) return;
|
||||
p_data.first() = octa::allocator_allocate(get_cpalloc(), p_size);
|
||||
memset(p_data.first(), 0, p_size * sizeof(Chain *));
|
||||
Chain **och = ht.p_data.first();
|
||||
for (octa::Size h = 0; h < p_size; ++h) {
|
||||
Chain *oc = och[h];
|
||||
for (; oc; oc = oc->next) {
|
||||
Chain *nc = insert(h);
|
||||
octa::allocator_destroy(get_alloc(), &nc->value);
|
||||
octa::allocator_construct(get_alloc(), &nc->value, oc->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Hashtable(Hashtable &&ht): p_size(ht.p_size), p_len(ht.p_len),
|
||||
p_chunks(ht.p_chunks), p_unused(ht.p_unused),
|
||||
p_data(octa::move(ht.p_data)), p_maxlf(ht.p_maxlf) {
|
||||
ht.p_size = ht.p_len = 0;
|
||||
ht.p_chunks = nullptr;
|
||||
ht.p_unused = nullptr;
|
||||
ht.p_data.first() = nullptr;
|
||||
}
|
||||
|
||||
Hashtable(Hashtable &&ht, const A &alloc): p_data(nullptr,
|
||||
FAPair(AllocPair(alloc, CoreAllocPair(alloc, alloc)),
|
||||
FuncPair(ht.get_hash(), ht.get_eq()))) {
|
||||
p_size = ht.p_size;
|
||||
if (alloc == ht.get_alloc()) {
|
||||
p_len = ht.p_len;
|
||||
p_chunks = ht.p_chunks;
|
||||
p_unused = ht.p_unused;
|
||||
p_data.first() = ht.p_data.first();
|
||||
p_maxlf = ht.p_maxlf;
|
||||
ht.p_size = ht.p_len = 0;
|
||||
ht.p_chunks = nullptr;
|
||||
ht.p_unused = nullptr;
|
||||
ht.p_data.first() = nullptr;
|
||||
return;
|
||||
}
|
||||
p_len = 0;
|
||||
p_chunks = nullptr;
|
||||
p_unused = nullptr;
|
||||
p_data.first() = octa::allocator_allocate(get_cpalloc(), p_size);
|
||||
memset(p_data.first(), 0, p_size * sizeof(Chain *));
|
||||
Chain **och = ht.p_data.first();
|
||||
for (octa::Size h = 0; h < p_size; ++h) {
|
||||
Chain *oc = och[h];
|
||||
for (; oc; oc = oc->next) {
|
||||
Chain *nc = insert(h);
|
||||
B::swap_elem(oc->value, nc->value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
~Hashtable() {
|
||||
octa::allocator_deallocate(get_cpalloc(), p_data.first(), p_size);
|
||||
if (p_size) octa::allocator_deallocate(get_cpalloc(),
|
||||
p_data.first(), p_size);
|
||||
delete_chunks(p_chunks);
|
||||
}
|
||||
|
||||
|
@ -304,7 +366,8 @@ namespace detail {
|
|||
}
|
||||
|
||||
void rehash(octa::Size count) {
|
||||
count = octa::max(count, octa::Size(p_len / max_load_factor()));
|
||||
octa::Size fbcount = octa::Size(p_len / max_load_factor());
|
||||
if (fbcount > count) count = fbcount;
|
||||
|
||||
Chain **och = p_data.first();
|
||||
Chain **nch = octa::allocator_allocate(get_cpalloc(), count);
|
||||
|
@ -327,7 +390,8 @@ namespace detail {
|
|||
}
|
||||
}
|
||||
|
||||
octa::allocator_deallocate(get_cpalloc(), och, osize);
|
||||
if (och && osize) octa::allocator_deallocate(get_cpalloc(),
|
||||
och, osize);
|
||||
delete_chunks(chunks);
|
||||
}
|
||||
|
||||
|
|
10
octa/map.h
10
octa/map.h
|
@ -78,6 +78,14 @@ public:
|
|||
Map(octa::Size size, const A &alloc): Map(size, H(), C(), alloc) {}
|
||||
Map(octa::Size size, const H &hf, const A &alloc): Map(size, hf, C(), alloc) {}
|
||||
|
||||
Map(const Map &m): p_table(m.p_table,
|
||||
octa::allocator_container_copy(m.p_table.get_alloc())) {}
|
||||
|
||||
Map(const Map &m, const A &alloc): p_table(m.p_table, alloc) {}
|
||||
|
||||
Map(Map &&m): p_table(octa::move(m.p_table)) {}
|
||||
Map(Map &&m, const A &alloc): p_table(octa::move(m.p_table), alloc) {}
|
||||
|
||||
template<typename R>
|
||||
Map(R range, octa::Size size = 1 << 10, const H &hf = H(),
|
||||
const C &eqf = C(), const A &alloc = A(),
|
||||
|
@ -123,7 +131,7 @@ public:
|
|||
void clear() { p_table.clear(); }
|
||||
|
||||
A get_allocator() const {
|
||||
return p_table.get_challoc();
|
||||
return p_table.get_alloc();
|
||||
}
|
||||
|
||||
T &at(const K &key) {
|
||||
|
|
|
@ -127,9 +127,8 @@ public:
|
|||
v.p_len = v.p_cap = 0;
|
||||
}
|
||||
|
||||
Vector(Vector &&v, const A &a) {
|
||||
if (a != v.a) {
|
||||
p_buf.second() = a;
|
||||
Vector(Vector &&v, const A &a): p_buf(nullptr, a) {
|
||||
if (!(a == v.p_buf.second())) {
|
||||
reserve(v.p_cap);
|
||||
p_len = v.p_len;
|
||||
if (octa::IsPod<T>()) {
|
||||
|
@ -144,8 +143,7 @@ public:
|
|||
}
|
||||
return;
|
||||
}
|
||||
new (&p_buf) VecPair(v.p_buf.first(),
|
||||
octa::move(v.p_buf.second()));
|
||||
p_buf.first() = v.p_buf.first();
|
||||
p_len = v.p_len;
|
||||
p_cap = v.p_cap;
|
||||
v.p_buf.first() = nullptr;
|
||||
|
|
Loading…
Reference in a new issue