TPIE

v1.1rc1-6-g0c97303
tokens.h
Go to the documentation of this file.
1 // -*- mode: c++; tab-width: 4; indent-tabs-mode: t; eval: (progn (c-set-style "stroustrup") (c-set-offset 'innamespace 0)); -*-
2 // vi:set ts=4 sts=4 sw=4 noet :
3 // Copyright 2012, The TPIE development team
4 //
5 // This file is part of TPIE.
6 //
7 // TPIE is free software: you can redistribute it and/or modify it under
8 // the terms of the GNU Lesser General Public License as published by the
9 // Free Software Foundation, either version 3 of the License, or (at your
10 // option) any later version.
11 //
12 // TPIE is distributed in the hope that it will be useful, but WITHOUT ANY
13 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 // License for more details.
16 //
17 // You should have received a copy of the GNU Lesser General Public License
18 // along with TPIE. If not, see <http://www.gnu.org/licenses/>
19 
70 
71 #ifndef __TPIE_PIPELINING_TOKENS_H__
72 #define __TPIE_PIPELINING_TOKENS_H__
73 
74 #include <tpie/exception.h>
75 #include <tpie/pipelining/exception.h>
77 #include <tpie/types.h>
78 #include <tpie/tpie_assert.h>
79 #include <map>
80 #include <iostream>
81 #include <boost/shared_ptr.hpp>
82 #include <boost/weak_ptr.hpp>
83 
84 namespace tpie {
85 
86 namespace pipelining {
87 
88 namespace bits {
89 
90 enum node_relation {
91  pushes,
92  pulls,
93  depends
94 };
95 
96 class node_map {
97 public:
98  typedef uint64_t id_t;
99  typedef node * val_t;
100 
101  typedef std::map<id_t, val_t> map_t;
102  typedef map_t::const_iterator mapit;
103 
104  typedef std::multimap<id_t, std::pair<id_t, node_relation> > relmap_t;
105  typedef relmap_t::const_iterator relmapit;
106 
107  typedef boost::shared_ptr<node_map> ptr;
108  typedef boost::weak_ptr<node_map> wptr;
109 
110  static inline ptr create() {
111  ptr result(new node_map);
112  result->self = wptr(result);
113  return result;
114  }
115 
116  inline id_t add_token(val_t token) {
117  id_t id = nextId++;
118  set_token(id, token);
119  return id;
120  }
121 
122  inline void set_token(id_t id, val_t token) {
123  assert_authoritative();
124  m_tokens[id] = token;
125  }
126 
127  // union-find link
128  void link(ptr target);
129 
130  inline void union_set(ptr target) {
131  find_authority()->link(target->find_authority());
132  }
133 
134  inline val_t get(id_t id) const {
135  mapit i = m_tokens.find(id);
136  if (i == m_tokens.end()) return 0;
137  return i->second;
138  }
139 
140  inline mapit begin() const {
141  return m_tokens.begin();
142  }
143 
144  inline mapit end() const {
145  return m_tokens.end();
146  }
147 
148  // union-find
149  ptr find_authority();
150 
151  inline void add_relation(id_t from, id_t to, node_relation rel) {
152  m_relations.insert(std::make_pair(from, std::make_pair(to, rel)));
153  m_relationsInv.insert(std::make_pair(to, std::make_pair(from, rel)));
154  }
155 
156  inline const relmap_t & get_relations() const {
157  return m_relations;
158  }
159 
160  inline size_t in_degree(id_t from, node_relation rel) const {
161  return out_degree(m_relationsInv, from, rel);
162  }
163 
164  inline size_t out_degree(id_t from, node_relation rel) const {
165  return out_degree(m_relations, from, rel);
166  }
167 
168  void assert_authoritative() const {
169  if (m_authority) throw non_authoritative_node_map();
170  }
171 
172  void dump(std::ostream & os = std::cout) const;
173 
178  void send_successors() const;
179 
180 private:
181  map_t m_tokens;
182  relmap_t m_relations;
183  relmap_t m_relationsInv;
184 
185  size_t out_degree(const relmap_t & map, id_t from, node_relation rel) const;
186 
187  wptr self;
188 
189  // union rank structure
190  ptr m_authority;
191  size_t m_rank;
192 
193  inline node_map()
194  : m_rank(0)
195  {
196  }
197 
198  inline node_map(const node_map &);
199  inline node_map & operator=(const node_map &);
200 
201  static id_t nextId;
202 };
203 
204 } // namespace bits
205 
206 class node_token {
207 public:
208  typedef bits::node_map::id_t id_t;
210 
211  // Use for the simple case in which a node owns its own token
212  inline node_token(val_t owner)
213  : m_tokens(bits::node_map::create())
214  , m_id(m_tokens->add_token(owner))
215  , m_free(false)
216  {
217  }
218 
219  // This copy constructor has two uses:
220  // 1. Simple case when a node is copied (freshToken = false)
221  // 2. Advanced case when a node is being constructed with a specific token (freshToken = true)
222  inline node_token(const node_token & other, val_t newOwner, bool freshToken = false)
223  : m_tokens(other.m_tokens->find_authority())
224  , m_id(other.id())
225  , m_free(false)
226  {
227  if (freshToken) {
228  if (!other.m_free)
229  throw exception("Trying to take ownership of a non-free token");
230  if (m_tokens->get(m_id) != 0)
231  throw exception("A token already has an owner, but m_free is true - contradiction");
232  } else {
233  if (other.m_free)
234  throw exception("Trying to copy a free token");
235  }
236  m_tokens->set_token(m_id, newOwner);
237  }
238 
239  // Use for the advanced case when a node_token is allocated before the node
240  inline node_token()
241  : m_tokens(bits::node_map::create())
242  , m_id(m_tokens->add_token(0))
243  , m_free(true)
244  {
245  }
246 
247  inline id_t id() const { return m_id; }
248 
249  inline bits::node_map::ptr map_union(const node_token & with) {
250  if (m_tokens == with.m_tokens) return m_tokens;
251  m_tokens->union_set(with.m_tokens);
252  return m_tokens = m_tokens->find_authority();
253  }
254 
255  inline bits::node_map::ptr get_map() const {
256  return m_tokens;
257  }
258 
259  inline val_t get() const {
260  return m_tokens->get(m_id);
261  }
262 
263 private:
264  bits::node_map::ptr m_tokens;
265  id_t m_id;
266  bool m_free;
267 };
268 
269 } // namespace pipelining
270 
271 } // namespace tpie
272 
273 #endif // __TPIE_PIPELINING_TOKENS_H__
Defines the tp_assert macro.
Standard types.
Exception classes.
Base class of all nodes.
Definition: node.h:58
Predeclarations of some pipelining classes.
void send_successors() const
Internal method called by graph_traits.