8#include <dispenso/graph.h>
14constexpr size_t kToDelete = std::numeric_limits<size_t>::max();
17 std::vector<const dispenso::BiPropNode*>& s1,
18 const std::vector<const dispenso::BiPropNode*>& s2) {
19 std::vector<const dispenso::BiPropNode*> tmp(s1);
21 std::set_union(tmp.cbegin(), tmp.cend(), s2.cbegin(), s2.cend(), std::back_inserter(s1));
25 auto it = std::upper_bound(s.begin(), s.end(), node);
26 if (it == s.begin() || *(it - 1) != node) {
34void BiPropNode::biPropDependsOnOneNode(BiPropNode& node) {
35 Node::dependsOnOneNode(node);
36 if (node.biPropSet_ ==
nullptr && biPropSet_ ==
nullptr) {
37 biPropSet_ = std::make_shared<std::vector<const BiPropNode*>>();
38 set_insert(*biPropSet_,
this);
39 set_insert(*biPropSet_, &node);
40 node.biPropSet_ = biPropSet_;
41 }
else if (node.biPropSet_ !=
nullptr && biPropSet_ !=
nullptr) {
42 set_union(*biPropSet_, *node.biPropSet_);
43 node.biPropSet_ = biPropSet_;
44 }
else if (biPropSet_ ==
nullptr) {
45 biPropSet_ = node.biPropSet_;
46 set_insert(*biPropSet_,
this);
48 node.biPropSet_ = biPropSet_;
49 set_insert(*biPropSet_, &node);
55 decrementDependentCounters();
65 for (NodeType*
n : nodes_) {
73SubgraphT<N>::~SubgraphT() {
74 for (NodeType* n : nodes_) {
80void SubgraphT<N>::decrementDependentCounters() {
81 for (N* node : nodes_) {
82 for (Node*
const dependent : node->dependents_) {
83 dependent->numPredecessors_--;
85 removeNodeFromBiPropSet(node);
90size_t SubgraphT<N>::markNodesWithPredicessors() {
91 size_t numGraphPredecessors = 0;
92 for (N* node : nodes_) {
93 if (node->numPredecessors_ != 0) {
94 numGraphPredecessors += node->numPredecessors_;
95 node->numPredecessors_ = kToDelete;
98 return numGraphPredecessors;
102void SubgraphT<N>::removePredecessorDependencies(
size_t numGraphPredecessors) {
103 for (SubgraphT<N>& subgraph : graph_->subgraphs_) {
104 if (&subgraph ==
this) {
107 for (N* node : subgraph.nodes_) {
108 std::vector<Node*>& dependents = node->dependents_;
109 size_t num = dependents.size();
110 for (
size_t i = 0; i < num;) {
111 if (dependents[i]->numPredecessors_ == kToDelete) {
112 dependents[i] = dependents[num - 1];
114 if (--numGraphPredecessors == 0) {
115 dependents.resize(num);
122 dependents.resize(num);
128constexpr size_t kMaxCache = 8;
132constexpr size_t kMaxChunkCapacity = 1 << 16;
134using AlignedNodePoolPtr =
135 std::unique_ptr<NoLockPoolAllocator, detail::AlignedFreeDeleter<NoLockPoolAllocator>>;
137std::vector<AlignedNodePoolPtr> g_sgcache[2];
138std::mutex g_sgcacheMtx;
141constexpr size_t kCacheIndex =
size_t{std::is_same<T, BiPropNode>::value};
146typename SubgraphT<N>::PoolPtr SubgraphT<N>::getAllocator() {
147 AlignedNodePoolPtr ptr;
149 auto& cache = g_sgcache[kCacheIndex<N>];
152 std::lock_guard<std::mutex> lk(g_sgcacheMtx);
155 detail::alignedMalloc(
sizeof(NoLockPoolAllocator),
alignof(NoLockPoolAllocator));
156 auto* pool =
new (alloc)
157 NoLockPoolAllocator(
sizeof(NodeType), 128 *
sizeof(NodeType), ::malloc, ::free);
160 ptr = std::move(cache.back());
165 return PoolPtr(ptr.release(), releaseAllocator);
169void SubgraphT<N>::releaseAllocator(NoLockPoolAllocator* ptr) {
173 if (ptr->totalChunkCapacity() < kMaxChunkCapacity) {
174 auto& cache = g_sgcache[kCacheIndex<N>];
176 std::lock_guard<std::mutex> lk(g_sgcacheMtx);
177 if (cache.size() < kMaxCache) {
178 cache.emplace_back(ptr);
183 detail::AlignedFreeDeleter<NoLockPoolAllocator>()(ptr);
195 subgraphs_ = std::move(
other.subgraphs_);
197 subgraph.graph_ =
this;
204 subgraphs_.push_back(SubgraphType(
this));
205 return subgraphs_.back();
const SubgraphT< N > & subgraph(size_t index) const
SubgraphT< N > & addSubgraph()
detail::OpResult< T > OpResult