diff --git a/Zcode/tree/node/family.hpp b/Zcode/tree/node/family.hpp index c41d1e0..cce9ce9 100644 --- a/Zcode/tree/node/family.hpp +++ b/Zcode/tree/node/family.hpp @@ -46,7 +46,7 @@ template inline bool isAncestor(Node_type A, Node_type X) { return (A.level()<=X.level()) - && (A.value&Node_type::maskpos) == (X.value&Node_type::AllOnes[A.level()]); + && (A.pos()) == (X.value&Node_type::AllOnes[A.level()]); } //! Do 2 Nodes share the same ancestor of a given level ? diff --git a/Zcode/tree/node/node.hpp b/Zcode/tree/node/node.hpp index 5d57b2d..31f1ecd 100644 --- a/Zcode/tree/node/node.hpp +++ b/Zcode/tree/node/node.hpp @@ -184,6 +184,18 @@ struct Node: public definitions return value&(XYZbit>>(dim*(level()+1))); } + //! Suppress all bits used to mark something. + inline void clearFreeBits() + { + value &= ~FreeBitsPart; + } + + //! Returns z-curve position of this node. + inline Node pos() const + { + return value & maskpos; + } + inline Node operator<<(std::size_t i) const { return {static_cast(value< return *this; } - inline bool operator&(Node const& node) const - { - return value&node.value; - } }; @@ -234,7 +242,7 @@ std::ostream& operator<<(std::ostream &os, const Node &node) for( int i = size-1; i >= 0; i-- ) { - if(node&(IntOne< operator&(Node const& node, value_ return {static_cast(node.value&value)}; } +template +inline Node operator&( value_type const& value, Node const& node ) +{ + return {static_cast(value&node.value)}; +} + template inline bool operator<(Node const& node1, Node const& node2) { diff --git a/Zcode/tree/slot/slot.hpp b/Zcode/tree/slot/slot.hpp index e6abd5c..c6a4c8e 100644 --- a/Zcode/tree/slot/slot.hpp +++ b/Zcode/tree/slot/slot.hpp @@ -42,7 +42,6 @@ struct slot: private std::vector< Node > static const node_value_type FreeBitsPart = node_type::FreeBitsPart; static const node_value_type voidbit = node_type::voidbit; - static const node_value_type maskpos = node_type::maskpos; static const node_value_type decal = dim*node_type::nlevels; node_type s1{0}, s2{node_type::AllOnes[node_type::nlevels-1]}; @@ -251,13 +250,13 @@ struct slot: private std::vector< Node > for(std::size_t i=0; i > //! sort by hash function. inline void sort() { - std::sort(begin(), end(), [&](auto &n1, auto &n2){return (n1.value&maskpos)<(n2.value&maskpos);}); + std::sort(begin(), end(), [&](auto &n1, auto &n2){return n1.pos() < n2.pos();}); } //! reallocate to reduce size; @@ -307,10 +306,10 @@ struct slot: private std::vector< Node > return ret; } - //! suppress all bits used to mark something (except voidbit). - inline void forgetFreeBits() + //! Suppress all bits used to mark something. + inline void clearFreeBits() { - std::for_each(begin(), end(), [&](auto &n){n.value&=(~FreeBitsPart);}); + std::for_each(begin(), end(), [](auto &n){ n.clearFreeBits(); }); } //! suppress ex-aequo. @@ -349,14 +348,14 @@ struct slot: private std::vector< Node > } //! return slotrank. - inline int Slotrank() const + inline int slotRank() const { return slotrank; } //! set the slot rank //! \param r - inline void setSlotrank(std::size_t r) + inline void setSlotRank(std::size_t r) { slotrank = r; } @@ -403,8 +402,8 @@ std::ostream& operator<<(std::ostream& os, const slot& sl) os << "s2: " << sl.s2 << "\n"; os << "size: " << sl.size() << "\n"; os << "capacity: " << sl.capacity() << "\n"; - os << "startrank: " << sl.Startrank() << "\n"; - os << "slotrank: " << sl.Slotrank() << "\n"; + os << "startrank: " << sl.startRank() << "\n"; + os << "slotrank: " << sl.slotRank() << "\n"; os << "hasvoidNodes: " << sl.hasvoidNodes() << "\n"; return os; } diff --git a/Zcode/tree/slot/slotCollection.hpp b/Zcode/tree/slot/slotCollection.hpp index 5c4fc0e..f198d0b 100644 --- a/Zcode/tree/slot/slotCollection.hpp +++ b/Zcode/tree/slot/slotCollection.hpp @@ -22,17 +22,13 @@ struct slotCollection : private std::vector< std::shared_ptr< slot>; using parent::operator[]; using parent::push_back; - using parent::insert; - using parent::erase; using parent::reserve; - using parent::resize; using parent::begin; using parent::end; using parent::cbegin; using parent::cend; using parent::size; using parent::capacity; - using parent::shrink_to_fit; using level_count_type = std::array; @@ -45,7 +41,7 @@ struct slotCollection : private std::vector< std::shared_ptr< slotcopyInArray(array.data()+sl->startRank()); }); } - //! make a "clone", ie copy all, but not the Nodes! - // \parameter C SlotCollection to be "cloned" - inline void clone(const slotCollection& C) - { - slot_min_size = C.slot_min_size; - slot_max_size = C.slot_max_size; - - for ( std::size_t i = 0; i < C.size(); ++i) - push_back(std::make_shared(C[i]->s1, C[i]->s2, C[i]->size()*node_type::treetype)); - } - - /// Is a Node abscissa in the interval [s1,s2[ ? - /// \param s1 - /// \param s2 - /// \param x Node to check. - /// \note x must be *not* hashed. - inline bool inInterval(node_type s1, node_type s2, node_type x) const - { - node_type xabs = x.hash()&node_type::maskpos; - return (s1<=xabs) && (s2>xabs); - } - /// Store one node using a cache. /// \param x the node to be inserted. /// \param cache an external Cache. inline void insert( node_type x, Cache& cache ) { - const node_type xh = x.hash(), xabs = xh&node_type::maskpos; + const node_type xh = x.hash(), xabs = xh.pos(); auto slot_ptr = cache.find(xabs); // Cache::find returns a shared_ptr. // std::shared_ptr convertion to bool returns true iff the shared_ptr is valid. @@ -129,7 +103,7 @@ struct slotCollection : private std::vector< std::shared_ptr< slotput(xh); } @@ -163,15 +137,15 @@ struct slotCollection : private std::vector< std::shared_ptr< slot& cache) const { - node_type xh = x.hash(), xabs = xh&node_type::maskpos; + node_type xh = x.hash(), xabs = xh.pos(); auto slot_ptr = cache.find(xabs); if( ! slot_ptr ) @@ -230,39 +204,31 @@ struct slotCollection : private std::vector< std::shared_ptr< slotfind(xh); return node_it == slot_ptr->cend() ? 0 : 1; } - //! remove all free bits from all nodes. - inline void forgetFreeBits() + //! Clear all free bits from all nodes. + inline void clearFreeBits() { - std::for_each(begin(), end(), [](auto& st){st->forgetFreeBits();}); + std::for_each(begin(), end(), [](auto& st){st->clearFreeBits();}); } - //! suppress void Nodes, if any. + //! Suppress void Nodes, if any. //! update the count of leaves. inline void compress(node_type val=node_type::voidbit) { std::for_each(begin(), end(), [&val](auto& st){st->compress(val);}); } + //! empty all the slots. inline void clear() { std::for_each(begin(), end(), [](auto& st){st->empty();}); } - //! make a copy (in a set) of the Nodes. - //! \param setN the set. - inline void makeExtern(SetNode& setN) - { - for (auto&st: this) - for(std::size_t i=0; isize(); ++i) - setN.insert(st[i]); - } - //! finalize: compute cumulsize (to allow rank function to work), and maximum //! size of slots; inline void finalize() @@ -270,13 +236,13 @@ struct slotCollection : private std::vector< std::shared_ptr< slotsetStartRank(0); - (*this)[0]->setSlotrank(0); + (*this)[0]->setSlotRank(0); for(std::size_t i=0; i 0) (*this)[i]->setStartRank((*this)[i-1]->startRank()+wmax); wmax = (*this)[i]->size(); - (*this)[i]->setSlotrank(i); + (*this)[i]->setSlotRank(i); } } @@ -285,15 +251,16 @@ struct slotCollection : private std::vector< std::shared_ptr< slotsetStartRank(0); - (*this)[0]->setSlotrank(0); + (*this)[0]->setSlotRank(0); for(std::size_t i=0; i0) (*this)[i]->setStartRank((*this)[i-1]->startRank()+wmax); wmax = (*this)[i]->size(); - (*this)[i]->setSlotrank(i); + (*this)[i]->setSlotRank(i); } } + //!return maximum size of slots. inline std::size_t maxSlotSize() const { diff --git a/test/test_slot.cpp b/test/test_slot.cpp index 0d71030..56ee02b 100644 --- a/test/test_slot.cpp +++ b/test/test_slot.cpp @@ -188,9 +188,12 @@ TYPED_TEST(SlotTest, compress) } slot.put(nodes); slot.setMark(node_type::voidbit); + // remove all odd nodes + EXPECT_EQ( slot.size(), 10 ); slot.compress(); EXPECT_EQ( slot.size(), 5 ); + for (std::size_t i=0; i<5; ++i) { node_type node{static_cast(2*i)}; @@ -446,7 +449,7 @@ TYPED_TEST(SlotTest, cutdown) EXPECT_EQ( slot.cutdown(3), false ); } -TYPED_TEST(SlotTest, forgetFreeBits) +TYPED_TEST(SlotTest, clearFreeBits) { auto const dim = TestFixture::dim; using value_type = typename TestFixture::value_type; @@ -457,7 +460,7 @@ TYPED_TEST(SlotTest, forgetFreeBits) for (std::size_t i=0; i<10; ++i) nodes[i] = i + node_type::voidbit; slot.put(nodes); - slot.forgetFreeBits(); + slot.clearFreeBits(); for (std::size_t i=0; i<10; ++i) { node_type node{static_cast(i)}; diff --git a/test/test_slotCollection.cpp b/test/test_slotCollection.cpp index 9fece1c..dc09b3a 100644 --- a/test/test_slotCollection.cpp +++ b/test/test_slotCollection.cpp @@ -39,26 +39,6 @@ TYPED_TEST(SlotCollectionTest, constructor) EXPECT_EQ( SCcopy[0]->size(), 1 ); } -TYPED_TEST(SlotCollectionTest, clone) -{ - auto const dim = TestFixture::dim; - using value_type = typename TestFixture::value_type; - using node_type = Node; - - slotCollection SC{2, 10, 10, 10}; - EXPECT_EQ( SC.capacity(), 2 ); - EXPECT_EQ( SC.size(), 1 ); - node_type n{1}; - SC.insert(n); - - slotCollection SCclone{}; - SCclone.clone(SC); - EXPECT_EQ( SCclone.capacity(), 1 ); - EXPECT_EQ( SCclone.size(), 1 ); - EXPECT_EQ( SCclone[0]->capacity(), SC[0]->size()*node_type::treetype ); - EXPECT_EQ( SCclone[0]->size(), 0 ); -} - TYPED_TEST(SlotCollectionTest, swap) { auto const dim = TestFixture::dim; @@ -124,9 +104,19 @@ TYPED_TEST(SlotCollectionTest, compress) using slot_type = slot; slotCollection SC{2, 10, 10, 11}; - SC.push_back(std::make_shared(10)); - + + const node_type n1{1}; + const node_type n2(2 + node_type::voidbit); + + SC.insert(n1); + SC.insert(n2); + + EXPECT_EQ( SC.nbNodes(), 2 ); + + SC[0]->setMark( node_type::voidbit ); // TODO: mark update should be triggered in slotCollection. SC.compress(); + + EXPECT_EQ( SC.nbNodes(), 1 ); } TYPED_TEST(SlotCollectionTest, nbNodes) @@ -247,3 +237,44 @@ TYPED_TEST(SlotCollectionTest, copyInArray) EXPECT_EQ( array[1], n2.hash() ); EXPECT_EQ( array[2], n3.hash() ); } + +TYPED_TEST(SlotCollectionTest, clearFreeBits) +{ + auto const dim = TestFixture::dim; + using value_type = typename TestFixture::value_type; + using node_type = Node; + + slotCollection SC{2, 10, 10, 11}; + const node_type n1{1}; + const node_type n2(n1.value + node_type::voidbit); + + SC.insert(n2); + + EXPECT_NE( (*SC[0])[0].value, n1.hash().value ); + + SC.clearFreeBits(); + + EXPECT_EQ( (*SC[0])[0].value, n1.hash().value ); +} + +TYPED_TEST(SlotCollectionTest, clear) +{ + auto const dim = TestFixture::dim; + using value_type = typename TestFixture::value_type; + using node_type = Node; + using slot_type = slot; + + slotCollection SC{2, 10, 10, 11}; + + const node_type n1{1}, n2{2}, n3{3}; + + SC.insert(n1); + SC.insert(n2); + SC.insert(n3); + + EXPECT_EQ( SC.nbNodes(), 3 ); + + SC.clear(); + + EXPECT_EQ( SC.nbNodes(), 0 ); +}