intrusive avl_set and offset_ptr
::type::pointer>::reference, const typename boost::intrusive::avltree_algorithms<typename boost::intrusive::detail::eval_if_c<boost::intrusive::avltree_impl<Config>::external_value_traits, boost::intrusive::detail::eval_value_traits<typename Config::value_traits>, boost::intrusive::detail::identity<typename Config::value_traits> ::type::node_traits>::insert_commit_data&) [with Config = boost::intrusive::avl_setopt<boost::intrusive::detail::base_hook_traits<tradescape::balance::BalanceNode, boost::intrusive::avltree_node_traits<boost::interprocess::offset_ptr<void>,
Hi, I try to use intrusive avl_set to put the set into a memory mapped file (I manage the file myself using just mapped_region. If I declare my node without offset_ptr my test program works as expected except that the pointers in the file are absolute. If I use offset_ptr I get a runtime assertion (see below). What I don't understand is why the assertion complains about uniqueness. Any help is appreciated! struct BalanceNode : public api::helper::BalanceKey // ,public bin::avl_set_base_hook<bin::optimize_size<true> > ,public bin::avl_set_base_hook< bin::optimize_size<true>, bin::void_pointer< bip::offset_ptr<void> > > { api::values::Decimal m_amount; }; // Define an avl_set using the base hook typedef bin::avl_set< BalanceNode > BalanceSet; /opt2/linux/x86_64/include/boost-1_35/boost/intrusive/avltree.hpp:618: boost::intrusive::tree_iterator<boost::intrusive::avltree_impl<Config>, false> boost::intrusive::avltree_impl<Config>::insert_unique_commit(typename std::iterator_traits<typename boost::intrusive::detail::eval_if_c<boost::intrusive::avltree_impl<Config>::external_value_traits, boost::intrusive::detail::eval_value_traits<typename Config::value_traits>, boost::intrusive::detail::identity<typename Config::value_traits> true>, safe_link, boost::intrusive::default_tag, 6>, std::less<tradescape::balance::BalanceNode>, long unsigned int, true>]: Assertion `node_algorithms::unique(to_insert)' failed. Lothar -- Lothar Werzinger Dipl.-Ing. Univ. framework & platform architect Tradescape Inc. - Enabling Efficient Digital Marketplaces 1754 Technology Drive, Suite 128 San Jose, CA 95110 web: http://www.tradescape.biz
Lothar Werzinger wrote:
Hi, I try to use intrusive avl_set to put the set into a memory mapped file (I manage the file myself using just mapped_region.
If I declare my node without offset_ptr my test program works as expected except that the pointers in the file are absolute. If I use offset_ptr I get a runtime assertion (see below). What I don't understand is why the assertion complains about uniqueness. Any help is appreciated!
Unless there is a bug (something that is of course, possible) if the assertion reaises in this function of avltree.hpp: iterator insert_unique_commit (reference value, const insert_commit_data &commit_data) { node_ptr to_insert(get_real_value_traits().to_node_ptr(value)); if(safemode_or_autounlink) BOOST_INTRUSIVE_SAFE_HOOK_DEFAULT_ASSERT (node_algorithms::unique(to_insert)); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ means that you've using a safe hook (the default one) and before inserting an object, the container checks that the hook is in default position (unique() is true). If it's not that means that the hook is still use (the value is still inserted in another container). The testsuite includes avl containers with offset_ptr<> pointers but this might indicate a bug in Intrusive. Please check if that object is still in another container and if not, it would be nice if you could provide a test case that raises the bug. Regards, Ion
On Wednesday 11 June 2008, Ion Gaztañaga wrote:
Unless there is a bug (something that is of course, possible) if the assertion reaises in this function of avltree.hpp:
iterator insert_unique_commit (node_algorithms::unique(to_insert)); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
means that you've using a safe hook (the default one) and before inserting an object, the container checks that the hook is in default position (unique() is true). If it's not that means that the hook is still use (the value is still inserted in another container). The testsuite includes avl containers with offset_ptr<> pointers but this might indicate a bug in Intrusive. Please check if that object is still in another container and if not, it would be nice if you could provide a test case that raises the bug.
Regards,
Ion
::type::pointer>::reference, const typename boost::intrusive::avltree_algorithms<typename boost::intrusive::detail::eval_if_c<boost::intrusive::avltree_impl<Config>::external_value_traits, boost::intrusive::detail::eval_value_traits<typename Config::value_traits>, boost::intrusive::detail::identity<typename Config::value_traits> ::type::node_traits>::insert_commit_data&) [with Config = boost::intrusive::avl_setopt<boost::intrusive::detail::base_hook_traits<BalanceNode, boost::intrusive::avltree_node_traits<boost::interprocess::offset_ptr<void>,
Hi Ion, find a simplified test case attached that reproduces my findings. Hopefully this will allow you to find the problem wether it is in my code or the library. g++ -o avltest -I/opt2/linux/x86_64/include/boost-1_35 -DUSE_OFFSET_PTR=1 avltest.cpp avltest.cpp:23:2: warning: #warning with offet_ptr rm /tmp/avltest.img; ./avltest sizeof(BalanceNode)=32 sizeof(BalanceSet)=32 creating file ... creating file done header.get_address()=0x7fb86cc72000 header.get_size()=128 region.get_address()=0x7fb86cc71080 region.get_size()=224 p_set=0x7fb86cc71080 p_values (before)=0x7fb86cc71080 offset=64 initializing header ... initializing header done p_header->m_avail=5 p_header->m_count=0 initializing set ... initializing set done p_values (after) =0x7fb86cc710c0 creating entry 0 ... creating entry 0 done int=84 inserting entry 0 ... avltest: /opt2/linux/x86_64/include/boost-1_35/boost/intrusive/avltree.hpp:618: boost::intrusive::tree_iterator<boost::intrusive::avltree_impl<Config>, false> boost::intrusive::avltree_impl<Config>::insert_unique_commit(typename std::iterator_traits<typename boost::intrusive::detail::eval_if_c<boost::intrusive::avltree_impl<Config>::external_value_traits, boost::intrusive::detail::eval_value_traits<typename Config::value_traits>, boost::intrusive::detail::identity<typename Config::value_traits> true>, safe_link, boost::intrusive::default_tag, 6>, std::less<BalanceNode>, long unsigned int, true>]: Assertion `node_algorithms::unique(to_insert)' failed. Aborted g++ -o avltest -I/opt2/linux/x86_64/include/boost-1_35 -DUSE_OFFSET_PTR=0 avltest.cpp avltest.cpp:20:2: warning: #warning without offet_ptr rm /tmp/avltest.img; ./avltest sizeof(BalanceNode)=32 sizeof(BalanceSet)=32 creating file ... creating file done header.get_address()=0x7f31b2dd4000 header.get_size()=128 region.get_address()=0x7f31b2dd3080 region.get_size()=224 p_set=0x7f31b2dd3080 p_values (before)=0x7f31b2dd3080 offset=64 initializing header ... initializing header done p_header->m_avail=5 p_header->m_count=0 initializing set ... initializing set done p_values (after) =0x7f31b2dd30c0 creating entry 0 ... creating entry 0 done int=84 inserting entry 0 ... inserting entry 0 done creating entry 1 ... creating entry 1 done int=85 inserting entry 1 ... inserting entry 1 done creating entry 2 ... creating entry 2 done int=86 inserting entry 2 ... inserting entry 2 done creating entry 3 ... creating entry 3 done int=87 inserting entry 3 ... inserting entry 3 done creating entry 4 ... creating entry 4 done int=88 inserting entry 4 ... inserting entry 4 done created/inserted 5 entries int=84 int=85 int=86 int=87 int=88 int=84 int=85 int=86 int=87 int=88 Thanks in advance! Lothar -- Lothar Werzinger Dipl.-Ing. Univ. framework & platform architect Tradescape Inc. - Enabling Efficient Digital Marketplaces 1754 Technology Drive, Suite 128 San Jose, CA 95110 web: http://www.tradescape.biz
On Wed, Jun 11, 2008 at 8:59 PM, Lothar Werzinger <lothar@tradescape.biz> wrote:
Hi Ion,
find a simplified test case attached that reproduces my findings. Hopefully this will allow you to find the problem wether it is in my code or the library.
Your test also raises the same error in Windows, and that's because you don't call the constructors of the hooks. Hooks have a constructor that put the hook in a safe state (so that it can be checked before inserting it). More on this on the documentation: http://www.boost.org/doc/libs/1_35_0/doc/html/intrusive/safe_hook.html Surely, memory will be initialized to zero when creating the file and zero is the safe state for raw pointers. On the other hand, offset pointers have a different default state (null is represented by offset == 1). Anyway, I can't guarantee that the test will work with those changes (I have no time to test this on a 64 bit machine and you are constructing objects directly in a mapped file calculating sizes with magic numbers that might change in another platform/compiler/OS). Try to construct all objects (placement new or similar) before inserting them in the container and see if the error disappears. Regards, Ion
On Thursday 12 June 2008, Ion Gaztañaga wrote:
Your test also raises the same error in Windows, and that's because you don't call the constructors of the hooks. Hooks have a constructor that put the hook in a safe state (so that it can be checked before inserting it). More on this on the documentation:
http://www.boost.org/doc/libs/1_35_0/doc/html/intrusive/safe_hook.html
Surely, memory will be initialized to zero when creating the file and zero is the safe state for raw pointers. On the other hand, offset pointers have a different default state (null is represented by offset == 1).
Thanks a lot. After inserting a placement new for every item the test works with offset_ptr; Lothar -- Lothar Werzinger Dipl.-Ing. Univ. framework & platform architect Tradescape Inc. - Enabling Efficient Digital Marketplaces 1754 Technology Drive, Suite 128 San Jose, CA 95110 web: http://www.tradescape.biz
participants (2)
-
Ion Gaztañaga
-
Lothar Werzinger