Skip to content

Commit faabeae

Browse files
committed
Container/MeshNetwork: Adding MultipleAccessor
1 parent 6ade2d6 commit faabeae

4 files changed

Lines changed: 102 additions & 80 deletions

File tree

modules/Container/MeshNetwork.mpp

Lines changed: 34 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,54 +20,54 @@ export namespace CppUtils::Container
2020
value{std::forward<decltype(args)>(args)...}
2121
{}
2222

23-
static inline auto attach(Accessor& node0Accessor, const Key& key1, SharedPtr& node1) -> void
24-
{
25-
node0Accessor->attachChild(node1);
26-
node0Accessor->value.branches[key1].push_back(node1);
27-
}
28-
2923
static inline auto attach(SharedPtr& node0, const Key& key1, SharedPtr& node1) -> void
3024
{
31-
auto node0Accessor = node0->uniqueAccess();
32-
attach(node0Accessor, key1, node1);
33-
}
25+
auto accessor = CppUtils::Thread::MultipleAccessor{*node0, *node1};
26+
auto& node0Ref = std::get<0>(accessor.values);
27+
auto& node1Ref = std::get<1>(accessor.values);
3428

35-
static inline auto detach(Accessor& node0Accessor, const Key& key1, SharedPtr& node1) -> void
36-
{
37-
auto& branches = node0Accessor->value.branches;
38-
auto& childs = branches[key1];
39-
if (auto it = std::find_if(std::cbegin(childs), std::cend(childs), [&](const auto& child) -> bool {
40-
return SafeShared{child} == node1;
41-
});
42-
it != std::cend(childs))
43-
childs.erase(it);
44-
if (std::empty(childs))
45-
branches.erase(key1);
46-
node0Accessor->detachChild(node1);
29+
node0Ref.attachChild(node1, node1Ref);
30+
node0Ref.value.branches[key1].push_back(node1);
4731
}
4832

4933
static inline auto detach(SharedPtr& node0, const Key& key1, SharedPtr& node1) -> void
5034
{
51-
auto node0Accessor = node0->uniqueAccess();
52-
detach(node0Accessor, key1, node1);
53-
}
35+
auto accessor = CppUtils::Thread::MultipleAccessor{*node0, *node1};
36+
auto& node0Ref = std::get<0>(accessor.values);
37+
auto& node1Ref = std::get<1>(accessor.values);
5438

55-
static inline auto detach(Accessor& nodeAccessor, const Key& key) -> void
56-
{
57-
auto& branches = nodeAccessor->value.branches;
58-
const auto& nodesToDetach = branches[key];
59-
for (const auto& nodeToDetach : nodesToDetach)
39+
auto& branches = node0Ref.value.branches;
40+
if (auto branchIt = branches.find(key1); branchIt != std::cend(branches))
6041
{
61-
auto sharedNode = nodeToDetach.lock();
62-
nodeAccessor->detachChild(sharedNode);
42+
auto& childs = branchIt->second;
43+
if (auto childIt = std::find_if(std::cbegin(childs), std::cend(childs), [&](const auto& child) -> bool {
44+
return SafeShared{child} == node1;
45+
});
46+
childIt != std::cend(childs))
47+
childs.erase(childIt);
48+
if (std::empty(childs))
49+
branches.erase(branchIt);
6350
}
64-
branches.erase(key);
51+
node0Ref.detachChild(node1, node1Ref);
6552
}
6653

6754
static inline auto detach(SharedPtr& node, const Key& key) -> void
6855
{
69-
auto nodeAccessor = node->uniqueAccess();
70-
detach(nodeAccessor, key);
56+
const auto nodesToDetach = [&node, &key] -> std::vector<WeakPtr> {
57+
auto nodeAccessor = node->uniqueAccess();
58+
auto& branches = nodeAccessor->value.branches;
59+
auto branch = branches[key];
60+
branches.erase(key);
61+
return branch;
62+
}();
63+
for (const auto& nodeToDetach : nodesToDetach)
64+
if (auto sharedNode = nodeToDetach.lock())
65+
{
66+
auto accessor = CppUtils::Thread::MultipleAccessor{*node, *sharedNode};
67+
auto& parentRef = std::get<0>(accessor.values);
68+
auto& childRef = std::get<1>(accessor.values);
69+
parentRef.detachChild(sharedNode, childRef);
70+
}
7171
}
7272

7373
static inline auto attach(const Key& key0, SharedPtr& node0, const Key& key1, SharedPtr& node1) -> void

modules/Container/NetworkPtr.mpp

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -79,24 +79,23 @@ export namespace CppUtils::Container
7979
return m_distanceFromRoot;
8080
}
8181

82-
inline auto attachChild(SharedPtr& childPtr) -> void
82+
inline auto attachChild(SharedPtr& childPtr, NetworkPtr& childValue) -> void
8383
{
8484
if (m_distanceFromRoot == std::numeric_limits<std::size_t>::max())
8585
throw std::logic_error{"Root node not found"};
86-
auto childAccessor = childPtr->uniqueAccess();
87-
if (not childAccessor->isRoot())
88-
if (std::empty(childAccessor->m_parents) or
89-
childAccessor->m_distanceFromRoot > m_distanceFromRoot + 1)
90-
childAccessor->m_distanceFromRoot = m_distanceFromRoot + 1;
86+
if (not childValue.isRoot())
87+
if (std::empty(childValue.m_parents) or
88+
childValue.m_distanceFromRoot > m_distanceFromRoot + 1)
89+
childValue.m_distanceFromRoot = m_distanceFromRoot + 1;
9190

92-
if (childAccessor->m_distanceFromRoot > m_distanceFromRoot)
91+
if (childValue.m_distanceFromRoot > m_distanceFromRoot)
9392
m_children.push_back(childPtr);
9493
else
9594
m_children.push_back(WeakPtr{childPtr});
96-
childAccessor->m_parents.push_back(m_weak_this);
95+
childValue.m_parents.push_back(m_weak_this);
9796
}
9897

99-
inline auto detachChild(SharedPtr& childPtr) -> void
98+
inline auto detachChild(SharedPtr& childPtr, NetworkPtr& childValue) -> void
10099
{
101100
if (auto thisPtr = m_weak_this.lock(); thisPtr)
102101
if (auto childIt = std::find_if(std::cbegin(m_children), std::cend(m_children), [&childPtr](const auto& child) -> bool {
@@ -108,8 +107,7 @@ export namespace CppUtils::Container
108107
{
109108
auto mustUpdateDistance = std::holds_alternative<SharedPtr>(*childIt);
110109
m_children.erase(childIt);
111-
auto childAccessor = childPtr->uniqueAccess();
112-
auto& parents = childAccessor->m_parents;
110+
auto& parents = childValue.m_parents;
113111
if (auto parentIt = std::find_if(
114112
std::cbegin(parents),
115113
std::cend(parents),
@@ -120,29 +118,36 @@ export namespace CppUtils::Container
120118
{
121119
parents.erase(parentIt);
122120
if (mustUpdateDistance)
123-
childAccessor->updateDistance(m_distanceFromRoot);
121+
childValue.updateDistance(m_distanceFromRoot);
124122
}
125123
}
126124
}
127125

128126
inline auto detachChildren() -> void
129127
{
130128
for (auto& child : m_children)
131-
if (std::holds_alternative<SharedPtr>(child))
132-
detachChild(std::get<SharedPtr>(child));
133-
else
129+
if (auto childPtr = std::visit([](auto&& pointer) -> SharedPtr {
130+
if constexpr (std::is_same_v<std::decay_t<decltype(pointer)>, SharedPtr>)
131+
return pointer;
132+
else
133+
return pointer.lock();
134+
}, child))
134135
{
135-
auto sharedPtr = std::get<WeakPtr>(child).lock();
136-
detachChild(sharedPtr);
136+
if (not childPtr)
137+
continue;
138+
auto accessor = childPtr->uniqueAccess();
139+
detachChild(childPtr, accessor.value());
137140
}
138141
}
139142

140143
inline auto detachParent(SharedPtr& parent) -> void
141144
{
142145
if (auto thisPtr = m_weak_this.lock(); thisPtr)
143146
{
144-
auto accessor = parent->uniqueAccess();
145-
accessor->detachChild(thisPtr);
147+
auto accessor = Thread::MultipleAccessor{*parent, *thisPtr};
148+
auto& parentRef = std::get<0>(accessor.values);
149+
auto& childRef = std::get<1>(accessor.values);
150+
parentRef.detachChild(thisPtr, childRef);
146151
}
147152
}
148153

@@ -152,8 +157,10 @@ export namespace CppUtils::Container
152157
for (const auto& parentWeak : m_parents)
153158
if (auto parent = parentWeak.lock())
154159
{
155-
auto accessor = parent->uniqueAccess();
156-
accessor->detachChild(thisPtr);
160+
auto accessor = Thread::MultipleAccessor{*parent, *thisPtr};
161+
auto& parentRef = std::get<0>(accessor.values);
162+
auto& childRef = std::get<1>(accessor.values);
163+
parentRef.detachChild(thisPtr, childRef);
157164
}
158165
}
159166

tests/Container/MeshNetwork.mpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,8 @@ export namespace CppUtils::UnitTest::Container::MeshNetwork
5858
auto fruit = StringMeshNode::makeRoot("fruit");
5959
auto apple = StringMeshNode::make("apple");
6060
auto banana = StringMeshNode::make("banana");
61-
{
62-
auto fruitAccessor = fruit->uniqueAccess();
63-
StringMeshNode::Value::attach(fruitAccessor, "Elements", apple);
64-
StringMeshNode::Value::attach(fruitAccessor, "Elements", banana);
65-
}
61+
StringMeshNode::Value::attach(fruit, "Elements", apple);
62+
StringMeshNode::Value::attach(fruit, "Elements", banana);
6663

6764
{
6865
auto fruitAccessor = fruit->sharedAccess();
@@ -116,11 +113,8 @@ export namespace CppUtils::UnitTest::Container::MeshNetwork
116113
auto fruit = StringMeshNode::makeRoot("fruit");
117114
auto apple = StringMeshNode::make("apple");
118115
auto banana = StringMeshNode::make("banana");
119-
{
120-
auto fruitAccessor = fruit->uniqueAccess();
121-
StringMeshNode::Value::attach(fruitAccessor, "Elements", apple);
122-
StringMeshNode::Value::attach(fruitAccessor, "Elements", banana);
123-
}
116+
StringMeshNode::Value::attach(fruit, "Elements", apple);
117+
StringMeshNode::Value::attach(fruit, "Elements", banana);
124118

125119
{
126120
auto fruitAccessor = fruit->sharedAccess();

tests/Container/NetworkPtr.mpp

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,10 @@ export namespace CppUtils::UnitTest::Container::NetworkPtr
4242
auto root = NetworkPtr::makeRoot("Root");
4343
{
4444
auto branch = NetworkPtr::make("Branch", 1uz);
45-
auto rootAccessor = root->uniqueAccess();
46-
rootAccessor->attachChild(branch);
45+
auto accessor = CppUtils::Thread::MultipleAccessor{*root, *branch};
46+
auto& rootRef = std::get<0>(accessor.values);
47+
auto& branchRef = std::get<1>(accessor.values);
48+
rootRef.attachChild(branch, branchRef);
4749
}
4850
Logger::print("Persistance de Branch\n");
4951
});
@@ -52,12 +54,18 @@ export namespace CppUtils::UnitTest::Container::NetworkPtr
5254
auto root = NetworkPtr::makeRoot("Root");
5355
{
5456
auto branch = NetworkPtr::make("Branch", 1uz);
55-
auto rootAccessor = root->uniqueAccess();
56-
rootAccessor->attachChild(branch);
57+
{
58+
auto accessor = CppUtils::Thread::MultipleAccessor{*root, *branch};
59+
auto& rootRef = std::get<0>(accessor.values);
60+
auto& branchRef = std::get<1>(accessor.values);
61+
rootRef.attachChild(branch, branchRef);
62+
}
5763
{
5864
auto leaf = NetworkPtr::make("Leaf", 2uz);
59-
auto branchAccessor = branch->uniqueAccess();
60-
branchAccessor->attachChild(leaf);
65+
auto accessor = CppUtils::Thread::MultipleAccessor{*branch, *leaf};
66+
auto& branchRef = std::get<0>(accessor.values);
67+
auto& leafRef = std::get<1>(accessor.values);
68+
branchRef.attachChild(leaf, leafRef);
6169
}
6270
Logger::print("Persistance de Leaf\n");
6371
}
@@ -68,15 +76,24 @@ export namespace CppUtils::UnitTest::Container::NetworkPtr
6876
auto root = NetworkPtr::makeRoot("Root");
6977
{
7078
auto branch = NetworkPtr::make("Branch", 1uz);
71-
auto rootAccessor = root->uniqueAccess();
72-
rootAccessor->attachChild(branch);
79+
{
80+
auto accessor = CppUtils::Thread::MultipleAccessor{*root, *branch};
81+
auto& rootRef = std::get<0>(accessor.values);
82+
auto& branchRef = std::get<1>(accessor.values);
83+
rootRef.attachChild(branch, branchRef);
84+
}
7385
{
7486
auto leaf = NetworkPtr::make("Leaf", 2uz);
75-
auto branchAccessor = branch->uniqueAccess();
76-
branchAccessor->attachChild(leaf);
87+
auto accessor = CppUtils::Thread::MultipleAccessor{*branch, *leaf};
88+
auto& branchRef = std::get<0>(accessor.values);
89+
auto& leafRef = std::get<1>(accessor.values);
90+
branchRef.attachChild(leaf, leafRef);
7791
}
7892
Logger::print("Persistance de Leaf\n");
79-
rootAccessor->detachChild(branch);
93+
auto accessor = CppUtils::Thread::MultipleAccessor{*root, *branch};
94+
auto& rootRef = std::get<0>(accessor.values);
95+
auto& branchRef = std::get<1>(accessor.values);
96+
rootRef.detachChild(branch, branchRef);
8097
}
8198
Logger::print("Non-persistance de Branch\n");
8299
});
@@ -86,14 +103,18 @@ export namespace CppUtils::UnitTest::Container::NetworkPtr
86103
auto branch = CppUtils::Container::SafeShared<NetworkPtr>{};
87104
{
88105
branch = NetworkPtr::make("Branch", 1uz);
89-
auto rootAccessor = root->uniqueAccess();
90-
rootAccessor->attachChild(branch);
106+
auto accessor = CppUtils::Thread::MultipleAccessor{*root, *branch};
107+
auto& rootRef = std::get<0>(accessor.values);
108+
auto& branchRef = std::get<1>(accessor.values);
109+
rootRef.attachChild(branch, branchRef);
91110
}
92111
Logger::print("Persistance de Branch\n");
93112
{
94-
auto branchAccessor = branch->uniqueAccess();
113+
auto accessor = CppUtils::Thread::MultipleAccessor{*root, *branch};
114+
auto& rootRef = std::get<0>(accessor.values);
115+
auto& branchRef = std::get<1>(accessor.values);
95116
Logger::print("Création d'une boucle\n");
96-
branchAccessor->attachChild(root);
117+
branchRef.attachChild(root, rootRef);
97118
}
98119
Logger::print("Libération de la boucle\n");
99120
});

0 commit comments

Comments
 (0)