From 2886f96544fec075c1eb8d605222bc85fd189054 Mon Sep 17 00:00:00 2001 From: Gregory Popovitch Date: Sat, 2 Nov 2024 19:21:18 -0400 Subject: [PATCH] Add support for custom pointers such as Boost Interprocess `offset_ptr` (#28) --- CMakeLists.txt | 69 ++++++++++++++++++-------------- examples/hmap/custom_pointer.cpp | 64 +++++++++++++++++++++++++++++ include/gtl/gtl_base.hpp | 3 +- include/gtl/phmap.hpp | 4 -- 4 files changed, 104 insertions(+), 36 deletions(-) create mode 100644 examples/hmap/custom_pointer.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index f1e76e3..f3cfeef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,6 +102,7 @@ option(GTL_BUILD_BENCHMARKS "Whether or not to build the benchmarks" ${GTL_MASTE if(MSVC) add_compile_options("$<$:/bigobj>") + set(natvis include/gtl/debug_vis/gtl.natvis) endif() if (GTL_BUILD_TESTS OR GTL_BUILD_EXAMPLES) @@ -165,48 +166,54 @@ if (GTL_BUILD_EXAMPLES) set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) - gtl_cc_app(ex_btree SRCS examples/btree/btree.cpp include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(ex_btree SRCS examples/btree/btree.cpp ${natvis}) - gtl_cc_app(ex_insert_bench SRCS examples/phmap/insert_bench.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_mt_word_counter SRCS examples/phmap/mt_word_counter.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_p_bench SRCS examples/phmap/p_bench.cpp include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(ex_insert_bench SRCS examples/phmap/insert_bench.cpp ${natvis}) + gtl_cc_app(ex_mt_word_counter SRCS examples/phmap/mt_word_counter.cpp ${natvis}) + gtl_cc_app(ex_p_bench SRCS examples/phmap/p_bench.cpp ${natvis}) if(MSVC) - gtl_cc_app(ex_lazy_emplace_l SRCS examples/phmap/lazy_emplace_l.cpp include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(ex_lazy_emplace_l SRCS examples/phmap/lazy_emplace_l.cpp ${natvis}) endif() - gtl_cc_app(ex_allmaps SRCS examples/hmap/allmaps.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_basic SRCS examples/hmap/basic.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_bench SRCS examples/hmap/bench.cpp include/gtl/debug_vis/gtl.natvis LIBS Threads::Threads) - gtl_cc_app(ex_emplace SRCS examples/hmap/emplace.cpp include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(ex_allmaps SRCS examples/hmap/allmaps.cpp ${natvis}) + gtl_cc_app(ex_basic SRCS examples/hmap/basic.cpp ${natvis}) + gtl_cc_app(ex_bench SRCS examples/hmap/bench.cpp ${natvis} LIBS Threads::Threads) + gtl_cc_app(ex_emplace SRCS examples/hmap/emplace.cpp ${natvis}) - gtl_cc_app(ex_serialize SRCS examples/hmap/serialize.cpp include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(ex_serialize SRCS examples/hmap/serialize.cpp ${natvis}) #target_include_directories(ex_serialize PUBLIC $) - gtl_cc_app(ex_hash SRCS examples/hmap/hash.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_hash_std SRCS examples/hmap/hash_std.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_hash_value SRCS examples/hmap/hash_value.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_two_files SRCS examples/hmap/f1.cpp examples/hmap/f2.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_knucleotide SRCS examples/hmap/knucleotide.cpp include/gtl/debug_vis/gtl.natvis LIBS Threads::Threads) - gtl_cc_app(ex_dump_load SRCS examples/hmap/dump_load.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_dump_nested SRCS examples/hmap/dump_nested.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_matt SRCS examples/hmap/matt.cpp include/gtl/debug_vis/gtl.natvis) - - gtl_cc_app(ex_soa SRCS examples/misc/soa.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_vec_utils SRCS examples/misc/vec_utils.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_bit_vector SRCS examples/misc/bit_vector.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_intrusive SRCS examples/misc/intrusive.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_utils SRCS "examples/misc/utils.cpp" include/gtl/debug_vis/gtl.natvis) - #gtl_cc_app(ex_adv_utils SRCS "examples/misc/adv_utils.cpp" include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(ex_hash SRCS examples/hmap/hash.cpp ${natvis}) + gtl_cc_app(ex_hash_std SRCS examples/hmap/hash_std.cpp ${natvis}) + gtl_cc_app(ex_hash_value SRCS examples/hmap/hash_value.cpp ${natvis}) + gtl_cc_app(ex_two_files SRCS examples/hmap/f1.cpp examples/hmap/f2.cpp ${natvis}) + gtl_cc_app(ex_knucleotide SRCS examples/hmap/knucleotide.cpp ${natvis} LIBS Threads::Threads) + gtl_cc_app(ex_dump_load SRCS examples/hmap/dump_load.cpp ${natvis}) + gtl_cc_app(ex_dump_nested SRCS examples/hmap/dump_nested.cpp ${natvis}) + gtl_cc_app(ex_matt SRCS examples/hmap/matt.cpp ${natvis}) + + gtl_cc_app(ex_soa SRCS examples/misc/soa.cpp ${natvis}) + gtl_cc_app(ex_vec_utils SRCS examples/misc/vec_utils.cpp ${natvis}) + gtl_cc_app(ex_bit_vector SRCS examples/misc/bit_vector.cpp ${natvis}) + gtl_cc_app(ex_intrusive SRCS examples/misc/intrusive.cpp ${natvis}) + gtl_cc_app(ex_utils SRCS "examples/misc/utils.cpp" ${natvis}) + #gtl_cc_app(ex_adv_utils SRCS "examples/misc/adv_utils.cpp" ${natvis}) ## cache/memoize - gtl_cc_app(ex_memoize_fib SRCS examples/memoize/memoize_fib.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_memoize_primes SRCS examples/memoize/memoize_primes.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(ex_mt_memoize SRCS examples/memoize/mt_memoize.cpp include/gtl/debug_vis/gtl.natvis LIBS Threads::Threads) - gtl_cc_app(ex_mt_memoize_lru SRCS examples/memoize/mt_memoize_lru.cpp include/gtl/debug_vis/gtl.natvis LIBS Threads::Threads) + gtl_cc_app(ex_memoize_fib SRCS examples/memoize/memoize_fib.cpp ${natvis}) + gtl_cc_app(ex_memoize_primes SRCS examples/memoize/memoize_primes.cpp ${natvis}) + gtl_cc_app(ex_mt_memoize SRCS examples/memoize/mt_memoize.cpp ${natvis} LIBS Threads::Threads) + gtl_cc_app(ex_mt_memoize_lru SRCS examples/memoize/mt_memoize_lru.cpp ${natvis} LIBS Threads::Threads) + + find_package(Boost 1.70.0) + if (Boost_FOUND) + gtl_cc_app(ex_custom_pointer SRCS examples/hmap/custom_pointer.cpp ${natvis}) + target_include_directories(ex_custom_pointer PRIVATE ${Boost_INCLUDE_DIRS}) + endif() endif() if (GTL_BUILD_BENCHMARKS) - gtl_cc_app(bench_bit_vector SRCS benchmarks/bitvector_bench.cpp include/gtl/debug_vis/gtl.natvis) - gtl_cc_app(bench_hash SRCS benchmarks/hash_bench.cpp include/gtl/debug_vis/gtl.natvis) + gtl_cc_app(bench_bit_vector SRCS benchmarks/bitvector_bench.cpp ${natvis}) + gtl_cc_app(bench_hash SRCS benchmarks/hash_bench.cpp ${natvis}) endif() diff --git a/examples/hmap/custom_pointer.cpp b/examples/hmap/custom_pointer.cpp new file mode 100644 index 0000000..dfd2841 --- /dev/null +++ b/examples/hmap/custom_pointer.cpp @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include +#include + +using mmap_file_t = boost::interprocess::managed_mapped_file; + +template +using bi_alloc_t = boost::interprocess::allocator; + +template +using scoped_alloc_t = std::scoped_allocator_adaptor; + +void simple_map() { + struct LatpLon { + int32_t latp; + int32_t lon; + }; + + using nodestore_pair_t = std::pair; + using map_t = gtl::flat_hash_map, std::equal_to, + bi_alloc_t>; + + auto mmap_file = + boost::interprocess::managed_mapped_file(boost::interprocess::open_or_create, "map_iv.dat", 1000000); + map_t* map = mmap_file.find_or_construct("node_store")(mmap_file.get_segment_manager()); + + for (unsigned int i = 0; i < 1000; ++i) { + LatpLon p = {10, 10}; + map->emplace(i, p); + } + + std::cout << map->at(10).latp << " " << map->at(10).lon << std::endl; +} + +void scoped_map() { + using way_t = std::vector>; + using waystore_pair_t = std::pair; + using map_t = gtl::flat_hash_map, std::equal_to, + std::scoped_allocator_adaptor>>; + + auto mmap_file = + boost::interprocess::managed_mapped_file(boost::interprocess::open_or_create, "map_iv.dat", 1000000); + map_t* map = mmap_file.find_or_construct("ways_store")(mmap_file.get_segment_manager()); + + for (unsigned int i = 0; i < 1000; ++i) { + std::vector init = {1, 2, 3, 4}; + map->emplace(std::piecewise_construct, std::forward_as_tuple(i), std::forward_as_tuple(init.begin(), init.end())); + } + + std::cout << map->at(10).size() << std::endl; + for (auto const& i : map->at(10)) + std::cout << i << " "; + std::cout << std::endl; +} + +int main() +{ + simple_map(); + scoped_map(); + return 0; +} \ No newline at end of file diff --git a/include/gtl/gtl_base.hpp b/include/gtl/gtl_base.hpp index 4866175..90c164c 100644 --- a/include/gtl/gtl_base.hpp +++ b/include/gtl/gtl_base.hpp @@ -903,7 +903,8 @@ void* Allocate(Alloc* alloc, size_t n) { using A = typename std::allocator_traits::template rebind_alloc; using AT = typename std::allocator_traits::template rebind_traits; A mem_alloc(*alloc); - void* p = AT::allocate(mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); + // `&*` below to support custom pointers such as boost offset_ptr. + void* p = &*AT::allocate(mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); assert(reinterpret_cast(p) % Alignment == 0 && "allocator does not respect alignment"); return p; } diff --git a/include/gtl/phmap.hpp b/include/gtl/phmap.hpp index 4b4f591..a72badb 100644 --- a/include/gtl/phmap.hpp +++ b/include/gtl/phmap.hpp @@ -1574,10 +1574,6 @@ class raw_hash_set { using IsDecomposable = IsDecomposable; public: - static_assert(std::is_same_v, "Allocators with custom pointer types are not supported"); - static_assert(std::is_same_v, - "Allocators with custom pointer types are not supported"); - class iterator { friend class raw_hash_set;