spot  1.2.1a
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
uf.hh
1 // Copyright (C) 2013 Laboratoire de Recherche et Développement
2 // de l'Epita (LRDE).
3 //
4 // This file is part of Spot, a model checking library.
5 //
6 // Spot is free software; you can redistribute it and/or modify it
7 // under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // Spot is distributed in the hope that it will be useful, but WITHOUT
12 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 // or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 // License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 
19 #ifndef SPOT_FASTTGBAALGOS_EC_CONCUR_UF_HH
20 # define SPOT_FASTTGBAALGOS_EC_CONCUR_UF_HH
21 
22 #include "fasttgba/fasttgba.hh"
23 #include <iosfwd>
24 #include <atomic>
25 
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29 
30 #include "fasttgbaalgos/ec/concur/unionfind.h"
31 
32 #ifdef __cplusplus
33 } // extern "C"
34 #endif
35 
36 
37 // ------------------------------------------------------------
38 // Wrapper for union find
39 // ============================================================
40 
41 static int
42 fasttgba_state_ptrint_cmp_wrapper(void *hash1, void *hash2)
43 {
44  const spot::fasttgba_state* l = (const spot::fasttgba_state*)hash1;
45  const spot::fasttgba_state* r = (const spot::fasttgba_state*)hash2;
46  assert(l && r);
47  return l->compare(r);
48 }
49 
50 uint32_t
51 fasttgba_state_ptrint_hash_wrapper(void *elt, void *ctx)
52 {
53  const spot::fasttgba_state* l = (const spot::fasttgba_state*)elt;
54  int hash = l->hash();
55  assert(hash);
56  return hash;
57  (void)ctx;
58 }
59 
60 void *
61 fasttgba_state_ptrint_clone_wrapper(void *key, void *ctx)
62 {
63  // FIXME?
64  assert(key);
65  return key;
66  (void)ctx;
67 }
68 
69 void
70 fasttgba_state_ptrint_free_wrapper(void *elt)
71 {
72  assert(elt);
73  //const spot::fasttgba_state* l = (const spot::fasttgba_state*)elt;
74  //l->destroy();
75  (void) elt;
76 }
77 
78 const size_t INIT_SCALE = 12;
79 static const datatype_t DATATYPE_INT_PTRINT =
80  {
81  fasttgba_state_ptrint_cmp_wrapper,
82  fasttgba_state_ptrint_hash_wrapper,
83  fasttgba_state_ptrint_clone_wrapper,
84  fasttgba_state_ptrint_free_wrapper
85  };
86 
97 namespace spot
98 {
99  class uf
100  {
101  public :
102  uf(int thread_number) : thread_number_(thread_number), size_(0)
103  {
104  effective_uf = uf_alloc(&DATATYPE_INT_PTRINT, INIT_SCALE, thread_number);
105  }
106 
107  virtual ~uf()
108  {
109  uf_free (effective_uf, true, thread_number_);
110  }
111 
113  bool make_set(const fasttgba_state* key, int tn)
114  {
115  // The Concurent Hash Map doesn't support key == 0 because
116  // it represent a special tag.
117  assert(key);
118 
119  int inserted = 0;
120  // uf_node_t* node;
121  // node =
122  uf_make_set(effective_uf, (map_key_t) key, &inserted, tn);
123  if (inserted)
124  ++size_;
125  return inserted;
126  }
127 
129  void make_dead(const fasttgba_state* key)
130  {
131  // The Concurent Hash Map doesn't support key == 0 because
132  // it represent a special tag.
133  assert(key);
134 
135  uf_node_t* node = (uf_node_t*)
136  ht_get(effective_uf->table, (map_key_t) key);
137  uf_make_dead(effective_uf, node);
138  }
139 
148  markset unite(const fasttgba_state* left, const fasttgba_state* right,
149  const markset acc, bool *is_dead)
150  {
151  uf_node_t* l = (uf_node_t*)
152  ht_get(effective_uf->table, (map_key_t) left);
153  uf_node_t* r = (uf_node_t*)
154  ht_get(effective_uf->table, (map_key_t) right);
155  unsigned long ret_acc = 0;
156 
157  uf_node_t* fast_ret = uf_unite (effective_uf, l, r, &ret_acc);
158  *is_dead = fast_ret == effective_uf->dead_;
159 
160  unsigned long tmp = acc.to_ulong();
161  // printf("%s %zu %zu\n", acc.dump().c_str(), tmp, ret_acc);
162  // The markset is empty don't need to go further
163 
164  if (!tmp || *is_dead || ret_acc == tmp)
165  return acc;
166 
167  // Grab the representative int.
168  unsigned long res = uf_add_acc(effective_uf, fast_ret, tmp);
169 
170  // if res equal 0 the state is dead!
171  // The add doesn't change anything
172  if (!res || tmp == res)
173  return acc;
174  return acc | res;
175  }
176 
178  bool is_dead(const fasttgba_state* key)
179  {
180  uf_node_t* node = (uf_node_t*)
181  ht_get(effective_uf->table, (map_key_t) key);
182 
183  if (node == DOES_NOT_EXIST)
184  return false;
185  return uf_is_dead(effective_uf, node);
186  }
187 
188  int size()
189  {
190  return size_;
191  }
192 
193  private:
194  uf_t* effective_uf;
195  int thread_number_;
196  std::atomic<int> size_;
197  };
198 }
199 #endif // SPOT_FASTTGBAALGOS_EC_CONCUR_UF_HH
Definition: uf.hh:99
This class act as an interface for all classes.
Definition: fasttgba_state.hh:30
virtual int compare(const fasttgba_state *other) const =0
Compares two states (that come from the same automaton).
bool make_set(const fasttgba_state *key, int tn)
insert a new element in the union find
Definition: uf.hh:113
void make_dead(const fasttgba_state *key)
Mark an elemnent as dead.
Definition: uf.hh:129
bool is_dead(const fasttgba_state *key)
check wether an element is linked to dead
Definition: uf.hh:178
markset unite(const fasttgba_state *left, const fasttgba_state *right, const markset acc, bool *is_dead)
Mark two states in the same set.
Definition: uf.hh:148
virtual size_t hash() const =0
Hash a state.
This class represents a set of acceptance marks.
Definition: markset.hh:35

Please direct any question, comment, or bug report to the Spot mailing list at spot@lrde.epita.fr.
Generated on Tue Jan 21 2014 16:52:01 for spot by doxygen 1.8.5