use allocators for hashtables always
parent
8324f5f9cc
commit
3b65b0cb99
|
@ -18,8 +18,8 @@ namespace octa {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename T>
|
template<typename T>
|
||||||
struct HashChain {
|
struct HashChain {
|
||||||
T value;
|
|
||||||
HashChain<T> *next;
|
HashChain<T> *next;
|
||||||
|
T value;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,7 +132,8 @@ namespace detail {
|
||||||
using CPA = octa::AllocatorRebind<A, Chain *>;
|
using CPA = octa::AllocatorRebind<A, Chain *>;
|
||||||
using CHA = octa::AllocatorRebind<A, Chunk>;
|
using CHA = octa::AllocatorRebind<A, Chunk>;
|
||||||
|
|
||||||
using AllocPair = octa::detail::CompressedPair<CPA, CHA>;
|
using CoreAllocPair = octa::detail::CompressedPair<CPA, CHA>;
|
||||||
|
using AllocPair = octa::detail::CompressedPair<A, CoreAllocPair>;
|
||||||
using FuncPair = octa::detail::CompressedPair<H, C>;
|
using FuncPair = octa::detail::CompressedPair<H, C>;
|
||||||
using FAPair = octa::detail::CompressedPair<AllocPair, FuncPair>;
|
using FAPair = octa::detail::CompressedPair<AllocPair, FuncPair>;
|
||||||
using DataPair = octa::detail::CompressedPair<Chain **, FAPair>;
|
using DataPair = octa::detail::CompressedPair<Chain **, FAPair>;
|
||||||
|
@ -149,12 +150,14 @@ namespace detail {
|
||||||
const H &get_hash() const { return p_data.second().second().first(); }
|
const H &get_hash() const { return p_data.second().second().first(); }
|
||||||
const C &get_eq() const { return p_data.second().second().second(); }
|
const C &get_eq() const { return p_data.second().second().second(); }
|
||||||
|
|
||||||
CPA &get_cpalloc() { return p_data.second().first().first(); }
|
A &get_alloc() { return p_data.second().first().first(); }
|
||||||
CHA &get_challoc() { return p_data.second().first().second(); }
|
CPA &get_cpalloc() { return p_data.second().first().second().first(); }
|
||||||
|
CHA &get_challoc() { return p_data.second().first().second().second(); }
|
||||||
|
|
||||||
Hashtable(octa::Size size, const H &hf, const C &eqf, const A &alloc):
|
Hashtable(octa::Size size, const H &hf, const C &eqf, const A &alloc):
|
||||||
p_size(size), p_len(0), p_chunks(nullptr), p_unused(nullptr),
|
p_size(size), p_len(0), p_chunks(nullptr), p_unused(nullptr),
|
||||||
p_data(nullptr, FAPair(AllocPair(alloc, alloc), FuncPair(hf, eqf))),
|
p_data(nullptr, FAPair(AllocPair(alloc, CoreAllocPair(alloc, alloc)),
|
||||||
|
FuncPair(hf, eqf))),
|
||||||
p_maxlf(1.0f) {
|
p_maxlf(1.0f) {
|
||||||
p_data.first() = octa::allocator_allocate(get_cpalloc(), size);
|
p_data.first() = octa::allocator_allocate(get_cpalloc(), size);
|
||||||
memset(p_data.first(), 0, size * sizeof(Chain *));
|
memset(p_data.first(), 0, size * sizeof(Chain *));
|
||||||
|
@ -191,7 +194,7 @@ namespace detail {
|
||||||
template<typename U>
|
template<typename U>
|
||||||
T &insert(octa::Size h, U &&key) {
|
T &insert(octa::Size h, U &&key) {
|
||||||
Chain *c = insert(h);
|
Chain *c = insert(h);
|
||||||
B::set_key(c->value, octa::forward<U>(key));
|
B::set_key(c->value, octa::forward<U>(key), get_alloc());
|
||||||
return B::get_data(c->value);
|
return B::get_data(c->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,8 +206,8 @@ namespace detail {
|
||||||
while (c) {
|
while (c) {
|
||||||
if (get_eq()(key, B::get_key(c->value))) {
|
if (get_eq()(key, B::get_key(c->value))) {
|
||||||
*p = c->next;
|
*p = c->next;
|
||||||
c->value.~E();
|
octa::allocator_destroy(get_alloc(), &c->value);
|
||||||
new (&c->value) E;
|
octa::allocator_construct(get_alloc(), &c->value);
|
||||||
c->next = p_unused;
|
c->next = p_unused;
|
||||||
p_unused = c;
|
p_unused = c;
|
||||||
--p_len;
|
--p_len;
|
||||||
|
|
11
octa/map.h
11
octa/map.h
|
@ -17,7 +17,7 @@
|
||||||
namespace octa {
|
namespace octa {
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template<typename K, typename T> struct MapBase {
|
template<typename K, typename T, typename A> struct MapBase {
|
||||||
using Element = octa::Pair<const K, T>;
|
using Element = octa::Pair<const K, T>;
|
||||||
|
|
||||||
static inline const K &get_key(Element &e) {
|
static inline const K &get_key(Element &e) {
|
||||||
|
@ -27,9 +27,10 @@ namespace detail {
|
||||||
return e.second;
|
return e.second;
|
||||||
}
|
}
|
||||||
template<typename U>
|
template<typename U>
|
||||||
static inline void set_key(Element &e, U &&key) {
|
static inline void set_key(Element &e, U &&key, A &alloc) {
|
||||||
e.first.~K();
|
octa::allocator_destroy(alloc, &e);
|
||||||
new ((K *)&e.first) K(octa::forward<U>(key));
|
octa::allocator_construct(alloc, &e, octa::forward<U>(key),
|
||||||
|
octa::move(T()));
|
||||||
}
|
}
|
||||||
static inline void swap_elem(Element &a, Element &b) {
|
static inline void swap_elem(Element &a, Element &b) {
|
||||||
octa::swap(*((K *)&a.first), *((K *)&b.first));
|
octa::swap(*((K *)&a.first), *((K *)&b.first));
|
||||||
|
@ -46,7 +47,7 @@ template<
|
||||||
> struct Map {
|
> struct Map {
|
||||||
private:
|
private:
|
||||||
using Base = octa::detail::Hashtable<
|
using Base = octa::detail::Hashtable<
|
||||||
octa::detail::MapBase<K, T>, octa::Pair<const K, T>, K, T, H, C, A
|
octa::detail::MapBase<K, T, A>, octa::Pair<const K, T>, K, T, H, C, A
|
||||||
>;
|
>;
|
||||||
Base p_table;
|
Base p_table;
|
||||||
public:
|
public:
|
||||||
|
|
Loading…
Reference in New Issue