- array_node * alloc_head_node() const
- {
- return alloc_array_node(head_size(), nullptr, 0);
- }
-
- array_node * alloc_array_node(array_node * pParent, size_t idxParent) const
- {
- return alloc_array_node(array_node_size(), pParent, idxParent);
- }
-
- static array_node * alloc_array_node(size_t nSize, array_node * pParent, size_t idxParent)
- {
- array_node * pNode = cxx_array_node_allocator().NewBlock(sizeof(array_node) + sizeof(atomic_node_ptr) * (nSize - 1), pParent, idxParent);
- new (pNode->nodes) atomic_node_ptr[nSize];
- return pNode;
- }
-
- static void free_array_node(array_node * parr)
- {
- cxx_array_node_allocator().Delete(parr);
- }
-
- void destroy_tree()
- {
- // The function is not thread-safe. For use in dtor only
- // Remove data node
- clear();
-
- // Destroy all array nodes
- destroy_array_nodes(m_Head, head_size());
- }
-
- void destroy_array_nodes(array_node * pArr, size_t nSize)
- {
- for (atomic_node_ptr * p = pArr->nodes, *pLast = pArr->nodes + nSize; p != pLast; ++p) {
- node_ptr slot = p->load(memory_model::memory_order_relaxed);
- if (slot.bits() == flag_array_node) {
- destroy_array_nodes(to_array(slot.ptr()), array_node_size());
- free_array_node(to_array(slot.ptr()));
- p->store(node_ptr(), memory_model::memory_order_relaxed);
- }
- }
- }
-
- void gather_level_statistics(std::vector<feldman_hashset::level_statistics>& stat, size_t nLevel, array_node * pArr, size_t nSize) const
- {
- if (stat.size() <= nLevel) {
- stat.resize(nLevel + 1);
- stat[nLevel].node_capacity = nSize;
- }
-
- ++stat[nLevel].array_node_count;
- for (atomic_node_ptr * p = pArr->nodes, *pLast = pArr->nodes + nSize; p != pLast; ++p) {
- node_ptr slot = p->load(memory_model::memory_order_relaxed);
- if (slot.bits() == flag_array_node) {
- ++stat[nLevel].array_cell_count;
- gather_level_statistics(stat, nLevel + 1, to_array(slot.ptr()), array_node_size());
- }
- else if (slot.bits() == flag_array_converting)
- ++stat[nLevel].array_cell_count;
- else if (slot.ptr())
- ++stat[nLevel].data_cell_count;
- else
- ++stat[nLevel].empty_cell_count;
- }
- }
-