Merge pull request #4413 from danpoe/refactor/sharing-map
Sharing map refactorings
This commit is contained in:
commit
039ac77841
|
@ -350,7 +350,7 @@ protected:
|
|||
|
||||
std::size_t count_unmarked_nodes(
|
||||
bool leafs_only,
|
||||
std::set<void *> &marked,
|
||||
std::set<const void *> &marked,
|
||||
bool mark = true) const;
|
||||
|
||||
// dummy element returned when no element was found
|
||||
|
@ -423,8 +423,10 @@ SHARING_MAPT(void)
|
|||
}
|
||||
|
||||
SHARING_MAPT(std::size_t)
|
||||
::count_unmarked_nodes(bool leafs_only, std::set<void *> &marked, bool mark)
|
||||
const
|
||||
::count_unmarked_nodes(
|
||||
bool leafs_only,
|
||||
std::set<const void *> &marked,
|
||||
bool mark) const
|
||||
{
|
||||
if(empty())
|
||||
return 0;
|
||||
|
@ -447,8 +449,10 @@ SHARING_MAPT(std::size_t)
|
|||
|
||||
// internal node or container node
|
||||
const innert *ip = static_cast<const innert *>(bp);
|
||||
const unsigned use_count = ip->data.use_count();
|
||||
void *raw_ptr = ip->data.get();
|
||||
const unsigned use_count = ip->use_count();
|
||||
const void *raw_ptr = ip->is_internal()
|
||||
? (const void *)&ip->read_internal()
|
||||
: (const void *)&ip->read_container();
|
||||
|
||||
if(use_count >= 2)
|
||||
{
|
||||
|
@ -488,8 +492,8 @@ SHARING_MAPT(std::size_t)
|
|||
|
||||
for(const auto &l : ll)
|
||||
{
|
||||
const unsigned leaf_use_count = l.data.use_count();
|
||||
void *leaf_raw_ptr = l.data.get();
|
||||
const unsigned leaf_use_count = l.use_count();
|
||||
const void *leaf_raw_ptr = &l.read();
|
||||
|
||||
if(leaf_use_count >= 2)
|
||||
{
|
||||
|
@ -528,7 +532,7 @@ SHARING_MAPT3(Iterator, , sharing_map_statst)
|
|||
Iterator end,
|
||||
std::function<sharing_mapt &(const Iterator)> f)
|
||||
{
|
||||
std::set<void *> marked;
|
||||
std::set<const void *> marked;
|
||||
sharing_map_statst sms;
|
||||
|
||||
// We do a separate pass over the tree for each statistic. This is not very
|
||||
|
|
|
@ -105,6 +105,9 @@ class sharing_node_baset
|
|||
SN_TYPE_PAR_DEF class sharing_node_innert : public sharing_node_baset
|
||||
{
|
||||
public:
|
||||
typedef small_shared_two_way_ptrt<SN_PTR_TYPE_ARGS> datat;
|
||||
typedef typename datat::use_countt use_countt;
|
||||
|
||||
typedef d_internalt<SN_TYPE_ARGS> d_it;
|
||||
typedef d_containert<SN_TYPE_ARGS> d_ct;
|
||||
|
||||
|
@ -113,18 +116,18 @@ public:
|
|||
typedef typename d_ct::leaft leaft;
|
||||
typedef typename d_ct::leaf_listt leaf_listt;
|
||||
|
||||
sharing_node_innert() : data(empty_data)
|
||||
sharing_node_innert()
|
||||
{
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return data == empty_data;
|
||||
return !data;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data = empty_data;
|
||||
data.reset();
|
||||
}
|
||||
|
||||
bool shares_with(const sharing_node_innert &other) const
|
||||
|
@ -134,6 +137,11 @@ public:
|
|||
return data == other.data;
|
||||
}
|
||||
|
||||
use_countt use_count() const
|
||||
{
|
||||
return data.use_count();
|
||||
}
|
||||
|
||||
void swap(sharing_node_innert &other)
|
||||
{
|
||||
data.swap(other.data);
|
||||
|
@ -151,22 +159,6 @@ public:
|
|||
return data.is_derived_v();
|
||||
}
|
||||
|
||||
d_it &write_internal()
|
||||
{
|
||||
if(data == empty_data)
|
||||
{
|
||||
data = make_shared_derived_u<SN_PTR_TYPE_ARGS>();
|
||||
}
|
||||
else if(data.use_count() > 1)
|
||||
{
|
||||
data = make_shared_derived_u<SN_PTR_TYPE_ARGS>(*data.get_derived_u());
|
||||
}
|
||||
|
||||
SN_ASSERT(data.use_count() == 1);
|
||||
|
||||
return *data.get_derived_u();
|
||||
}
|
||||
|
||||
const d_it &read_internal() const
|
||||
{
|
||||
SN_ASSERT(!empty());
|
||||
|
@ -174,22 +166,6 @@ public:
|
|||
return *data.get_derived_u();
|
||||
}
|
||||
|
||||
d_ct &write_container()
|
||||
{
|
||||
if(data == empty_data)
|
||||
{
|
||||
data = make_shared_derived_v<SN_PTR_TYPE_ARGS>();
|
||||
}
|
||||
else if(data.use_count() > 1)
|
||||
{
|
||||
data = make_shared_derived_v<SN_PTR_TYPE_ARGS>(*data.get_derived_v());
|
||||
}
|
||||
|
||||
SN_ASSERT(data.use_count() == 1);
|
||||
|
||||
return *data.get_derived_v();
|
||||
}
|
||||
|
||||
const d_ct &read_container() const
|
||||
{
|
||||
SN_ASSERT(!empty());
|
||||
|
@ -338,13 +314,41 @@ public:
|
|||
SN_ASSERT_USE(r, r == 1);
|
||||
}
|
||||
|
||||
small_shared_two_way_ptrt<SN_PTR_TYPE_ARGS> data;
|
||||
static small_shared_two_way_ptrt<SN_PTR_TYPE_ARGS> empty_data;
|
||||
};
|
||||
protected:
|
||||
d_it &write_internal()
|
||||
{
|
||||
if(!data)
|
||||
{
|
||||
data = make_shared_derived_u<SN_PTR_TYPE_ARGS>();
|
||||
}
|
||||
else if(data.use_count() > 1)
|
||||
{
|
||||
data = make_shared_derived_u<SN_PTR_TYPE_ARGS>(*data.get_derived_u());
|
||||
}
|
||||
|
||||
SN_TYPE_PAR_DEF small_shared_two_way_ptrt<SN_PTR_TYPE_ARGS>
|
||||
sharing_node_innert<SN_TYPE_ARGS>::empty_data =
|
||||
small_shared_two_way_ptrt<SN_PTR_TYPE_ARGS>();
|
||||
SN_ASSERT(data.use_count() == 1);
|
||||
|
||||
return *data.get_derived_u();
|
||||
}
|
||||
|
||||
d_ct &write_container()
|
||||
{
|
||||
if(!data)
|
||||
{
|
||||
data = make_shared_derived_v<SN_PTR_TYPE_ARGS>();
|
||||
}
|
||||
else if(data.use_count() > 1)
|
||||
{
|
||||
data = make_shared_derived_v<SN_PTR_TYPE_ARGS>(*data.get_derived_v());
|
||||
}
|
||||
|
||||
SN_ASSERT(data.use_count() == 1);
|
||||
|
||||
return *data.get_derived_v();
|
||||
}
|
||||
|
||||
datat data;
|
||||
};
|
||||
|
||||
// Leafs
|
||||
|
||||
|
@ -362,9 +366,12 @@ public:
|
|||
SN_TYPE_PAR_DEF class sharing_node_leaft : public sharing_node_baset
|
||||
{
|
||||
public:
|
||||
typedef small_shared_ptrt<SN_PTR_TYPE_ARG> datat;
|
||||
typedef decltype(datat().use_count()) use_countt;
|
||||
|
||||
typedef d_leaft<SN_TYPE_ARGS> d_lt;
|
||||
|
||||
sharing_node_leaft(const keyT &k, const valueT &v) : data(empty_data)
|
||||
sharing_node_leaft(const keyT &k, const valueT &v)
|
||||
{
|
||||
SN_ASSERT(empty());
|
||||
|
||||
|
@ -384,12 +391,12 @@ public:
|
|||
|
||||
bool empty() const
|
||||
{
|
||||
return data == empty_data;
|
||||
return !data;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
data = empty_data;
|
||||
data.reset();
|
||||
}
|
||||
|
||||
bool shares_with(const sharing_node_leaft &other) const
|
||||
|
@ -397,34 +404,16 @@ public:
|
|||
return data == other.data;
|
||||
}
|
||||
|
||||
use_countt use_count() const
|
||||
{
|
||||
return data.use_count();
|
||||
}
|
||||
|
||||
void swap(sharing_node_leaft &other)
|
||||
{
|
||||
data.swap(other.data);
|
||||
}
|
||||
|
||||
d_lt &write()
|
||||
{
|
||||
SN_ASSERT(data.use_count() > 0);
|
||||
|
||||
if(data == empty_data)
|
||||
{
|
||||
data = make_small_shared_ptr<d_lt>();
|
||||
}
|
||||
else if(data.use_count() > 1)
|
||||
{
|
||||
data = make_small_shared_ptr<d_lt>(*data);
|
||||
}
|
||||
|
||||
SN_ASSERT(data.use_count() == 1);
|
||||
|
||||
return *data;
|
||||
}
|
||||
|
||||
const d_lt &read() const
|
||||
{
|
||||
return *data;
|
||||
}
|
||||
|
||||
// Accessors
|
||||
|
||||
const keyT &get_key() const
|
||||
|
@ -452,12 +441,29 @@ public:
|
|||
return write().v;
|
||||
}
|
||||
|
||||
small_shared_ptrt<SN_PTR_TYPE_ARG> data;
|
||||
static small_shared_ptrt<SN_PTR_TYPE_ARG> empty_data;
|
||||
const d_lt &read() const
|
||||
{
|
||||
return *data;
|
||||
}
|
||||
|
||||
protected:
|
||||
d_lt &write()
|
||||
{
|
||||
if(!data)
|
||||
{
|
||||
data = make_small_shared_ptr<d_lt>();
|
||||
}
|
||||
else if(data.use_count() > 1)
|
||||
{
|
||||
data = make_small_shared_ptr<d_lt>(*data);
|
||||
}
|
||||
|
||||
SN_ASSERT(data.use_count() == 1);
|
||||
|
||||
return *data;
|
||||
}
|
||||
|
||||
datat data;
|
||||
};
|
||||
|
||||
SN_TYPE_PAR_DEF small_shared_ptrt<SN_PTR_TYPE_ARG>
|
||||
sharing_node_leaft<SN_TYPE_ARGS>::empty_data =
|
||||
make_small_shared_ptr<SN_PTR_TYPE_ARG>();
|
||||
|
||||
#endif
|
||||
|
|
|
@ -101,30 +101,13 @@ public:
|
|||
|
||||
~small_shared_two_way_ptrt()
|
||||
{
|
||||
if(!p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
destruct();
|
||||
}
|
||||
|
||||
auto use_count = p->use_count();
|
||||
|
||||
if(use_count == 1)
|
||||
{
|
||||
if(p->is_derived_u())
|
||||
{
|
||||
U *u = static_cast<U *>(p);
|
||||
delete u;
|
||||
}
|
||||
else
|
||||
{
|
||||
V *v = static_cast<V *>(p);
|
||||
delete v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->decrement_use_count();
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
destruct();
|
||||
p = nullptr;
|
||||
}
|
||||
|
||||
void swap(small_shared_two_way_ptrt &rhs)
|
||||
|
@ -186,6 +169,34 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
void destruct()
|
||||
{
|
||||
if(!p)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
auto use_count = p->use_count();
|
||||
|
||||
if(use_count == 1)
|
||||
{
|
||||
if(p->is_derived_u())
|
||||
{
|
||||
U *u = static_cast<U *>(p);
|
||||
delete u;
|
||||
}
|
||||
else
|
||||
{
|
||||
V *v = static_cast<V *>(p);
|
||||
delete v;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
p->decrement_use_count();
|
||||
}
|
||||
}
|
||||
|
||||
pointeet *p = nullptr;
|
||||
};
|
||||
|
||||
|
|
|
@ -385,7 +385,7 @@ void sharing_map_sharing_stats_test()
|
|||
{
|
||||
SECTION("count nodes")
|
||||
{
|
||||
std::set<void *> marked;
|
||||
std::set<const void *> marked;
|
||||
smt sm;
|
||||
int count = 0;
|
||||
|
||||
|
@ -410,7 +410,7 @@ void sharing_map_sharing_stats_test()
|
|||
|
||||
SECTION("marking")
|
||||
{
|
||||
std::set<void *> marked;
|
||||
std::set<const void *> marked;
|
||||
smt sm;
|
||||
|
||||
fill(sm);
|
||||
|
|
|
@ -7,7 +7,37 @@
|
|||
#include <testing-utils/use_catch.h>
|
||||
#include <util/sharing_node.h>
|
||||
|
||||
void sharing_node_test()
|
||||
class leaft : public sharing_node_leaft<int, int>
|
||||
{
|
||||
public:
|
||||
leaft(const int &a, const int &b) : sharing_node_leaft<int, int>(a, b)
|
||||
{
|
||||
}
|
||||
friend void sharing_node_internals_test();
|
||||
};
|
||||
|
||||
void sharing_node_internals_test()
|
||||
{
|
||||
SECTION("Leaf test")
|
||||
{
|
||||
// Detaching
|
||||
{
|
||||
leaft leaf(1, 2);
|
||||
|
||||
auto p = leaf.data.get();
|
||||
leaf.write();
|
||||
|
||||
REQUIRE(leaf.data.get() == p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Sharing node internals", "[core][util]")
|
||||
{
|
||||
sharing_node_internals_test();
|
||||
}
|
||||
|
||||
TEST_CASE("Sharing node", "[core][util]")
|
||||
{
|
||||
SECTION("Leaf test")
|
||||
{
|
||||
|
@ -45,16 +75,6 @@ void sharing_node_test()
|
|||
REQUIRE(leaf2.get_value() == 3);
|
||||
REQUIRE(!leaf2.shares_with(leaf1));
|
||||
}
|
||||
|
||||
// Detaching
|
||||
{
|
||||
leaft leaf(1, 2);
|
||||
|
||||
auto p = leaf.data.get();
|
||||
leaf.write();
|
||||
|
||||
REQUIRE(leaf.data.get() == p);
|
||||
}
|
||||
}
|
||||
|
||||
SECTION("Inner node test")
|
||||
|
@ -201,8 +221,3 @@ void sharing_node_test()
|
|||
REQUIRE(map2.shares_with(map));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Sharing node")
|
||||
{
|
||||
sharing_node_test();
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ TEST_CASE("Small shared two-way pointer")
|
|||
SECTION("Basic")
|
||||
{
|
||||
spt sp1;
|
||||
REQUIRE(!sp1);
|
||||
REQUIRE(sp1.use_count() == 0);
|
||||
|
||||
const d1t *p;
|
||||
|
@ -86,6 +87,10 @@ TEST_CASE("Small shared two-way pointer")
|
|||
REQUIRE(sp1.use_count() == 3);
|
||||
REQUIRE(sp2.use_count() == 3);
|
||||
REQUIRE(sp3.use_count() == 3);
|
||||
|
||||
sp1.reset();
|
||||
REQUIRE(!sp1);
|
||||
REQUIRE(sp1.use_count() == 0);
|
||||
}
|
||||
|
||||
SECTION("Creation")
|
||||
|
|
Loading…
Reference in New Issue