71 #ifndef __TPIE_PIPELINING_TOKENS_H__
72 #define __TPIE_PIPELINING_TOKENS_H__
74 #include <tpie/tpie_export.h>
76 #include <tpie/pipelining/exception.h>
78 #include <tpie/pipelining/container.h>
84 #include <boost/intrusive_ptr.hpp>
85 #include <boost/optional.hpp>
86 #include <unordered_map>
87 #include <unordered_set>
102 typedef uint64_t id_t;
105 typedef std::map<id_t, val_t> map_t;
106 typedef map_t::const_iterator mapit;
108 typedef std::multimap<id_t, std::pair<id_t, node_relation> > relmap_t;
109 typedef relmap_t::const_iterator relmapit;
111 typedef std::unordered_map<std::string, std::pair<memory_size_type, any_noncopyable> > datastructuremap_t;
113 typedef boost::optional<any_noncopyable &> maybeany_t;
114 typedef std::unordered_map<std::string, any_noncopyable> forwardmap_t;
116 typedef boost::intrusive_ptr<node_map> ptr;
117 typedef std::unique_ptr<node> owned_ptr;
125 static ptr create() {
129 id_t add_token(val_t token) {
131 set_token(
id, token);
135 void set_token(id_t
id, val_t token) {
136 assert_authoritative();
137 m_tokens[id] = token;
141 void link(ptr target);
143 void union_set(ptr target) {
144 find_authority()->link(target->find_authority());
147 val_t get(id_t
id)
const {
148 mapit i = m_tokens.find(
id);
149 if (i == m_tokens.end())
return 0;
153 mapit begin()
const {
154 return m_tokens.begin();
158 return m_tokens.end();
161 size_t size()
const {
162 return m_tokens.size();
165 void no_forward_through(id_t
id) {
166 m_noForwardThrough.insert(
id);
170 ptr find_authority();
172 void add_relation(id_t from, id_t to, node_relation rel);
174 const relmap_t & get_relations()
const {
178 const datastructuremap_t & get_datastructures()
const {
179 return m_datastructures;
182 datastructuremap_t & get_datastructures() {
183 return m_datastructures;
186 size_t in_degree(id_t from, node_relation rel)
const {
187 return out_degree(m_relationsInv, from, rel);
190 size_t out_degree(id_t from, node_relation rel)
const {
191 return out_degree(m_relations, from, rel);
194 size_t out_degree(id_t from)
const {
195 return out_degree(m_relations, from);
198 void assert_authoritative()
const {
199 if (m_authority)
throw non_authoritative_node_map();
202 void dump(std::ostream & os = std::cout)
const;
208 void get_successors(id_t from, std::vector<id_t> & successors, memory_size_type k,
bool forward_only=
false);
210 void forward(std::string key, any_noncopyable value) {
211 m_pipelineForwards[key] = std::move(value);
214 maybeany_t fetch_maybe(std::string key) {
215 auto it = m_pipelineForwards.find(key);
216 if (it == m_pipelineForwards.end()) {
219 return maybeany_t(it->second);
222 void forward_from_pipe_base(id_t from, std::string key, any_noncopyable value) {
223 m_pipeBaseForwards.push_back({from, key, std::move(value)});
226 void forward_pipe_base_forwards();
228 friend void intrusive_ptr_add_ref(node_map * m) {
232 friend void intrusive_ptr_release(node_map * m) {
234 if (m->m_refCnt == 0)
delete m;
237 void increment_pipeline_ref() {
238 assert_authoritative();
242 void decrement_pipeline_ref() {
243 assert_authoritative();
245 if (m_pipelineRefCnt == 0) {
250 m_ownedNodes.clear();
254 void add_owned_node(owned_ptr p) {
255 m_ownedNodes.push_back(std::move(p));
261 size_t m_pipelineRefCnt;
262 relmap_t m_relations;
263 relmap_t m_relationsInv;
264 datastructuremap_t m_datastructures;
265 forwardmap_t m_pipelineForwards;
266 std::unordered_set<id_t> m_noForwardThrough;
267 std::vector<pipe_base_forward_t> m_pipeBaseForwards;
268 std::vector<owned_ptr> m_ownedNodes;
270 size_t out_degree(
const relmap_t &
map, id_t from, node_relation rel)
const;
271 size_t out_degree(
const relmap_t &
map, id_t from)
const;
279 , m_pipelineRefCnt(0)
284 inline node_map(
const node_map &);
285 inline node_map & operator=(
const node_map &);
294 typedef bits::node_map::id_t id_t;
299 : m_tokens(bits::node_map::create())
300 , m_id(m_tokens->add_token(owner))
309 : m_tokens(other.m_tokens->find_authority())
315 throw exception(
"Trying to take ownership of a non-free token");
316 if (m_tokens->get(m_id) != 0)
317 throw exception(
"A token already has an owner, but m_free is true - contradiction");
320 throw exception(
"Trying to copy a free token");
322 m_tokens->set_token(m_id, newOwner);
325 void assign(
const node_token & other,
val_t newOwner,
bool freshToken =
false) {
326 m_tokens = other.m_tokens->find_authority();
331 throw exception(
"Trying to take ownership of a non-free token");
332 if (m_tokens->get(m_id) != 0)
333 throw exception(
"A token already has an owner, but m_free is true - contradiction");
336 throw exception(
"Trying to copy a free token");
338 m_tokens->set_token(m_id, newOwner);
343 : m_tokens(bits::node_map::create())
344 , m_id(m_tokens->add_token(0))
349 id_t id()
const {
return m_id; }
351 bits::node_map::ptr map_union(
const node_token & with) {
352 if (m_tokens != with.m_tokens)
353 m_tokens->union_set(with.m_tokens);
354 return m_tokens = m_tokens->find_authority();
357 bits::node_map::ptr get_map()
const {
362 return m_tokens->get(m_id);
366 bits::node_map::ptr m_tokens;
373 #endif // __TPIE_PIPELINING_TOKENS_H__