1 //////////////////////////////////////////////////////////////////////////////
4 // ADLib, Prop and their related set of tools and documentation are in the
5 // public domain. The author(s) of this software reserve no copyrights on
6 // the source code and any code generated using the tools. You are encouraged
7 // to use ADLib and Prop to develop software, in both academic and commercial
8 // settings, and are free to incorporate any part of ADLib and Prop into
11 // Although you are under no obligation to do so, we strongly recommend that
12 // you give away all software developed using our tools.
14 // We also ask that credit be given to us when ADLib and/or Prop are used in
15 // your programs, and that this notice be preserved intact in all the source
18 // This software is still under development and we welcome any suggestions
19 // and help from the users.
23 //////////////////////////////////////////////////////////////////////////////
25 #ifndef faster_bit_set_h
26 #define faster_bit_set_h
28 //////////////////////////////////////////////////////////////////////////////
29 // Faster bitsets which changes its internal representation according
31 //////////////////////////////////////////////////////////////////////////////
33 #include <AD/contain/bitset.h>
40 enum { EMPTY
, SINGLETON
, SPARSE
, DENSE
} kind
;
41 enum { MAX_SPARSE
= 8 };
42 int capacity
; // maximum number of elements
43 short * sparse_set
; // place to store the sparse set
44 BitSet
* dense_set
; // place to store the dense set
46 int one_bit
; // place to store one bit
47 int count
; // number of elements stored
53 { const short * cursor
;
55 const BitSet
* bitset
;
61 inline Iter() : cursor(tmp
) { tmp
[0] = -1; }
62 inline Iter(const Iter
& i
) { *this = i
; }
63 inline Iter(const FastBitSet
& s
);
65 { if (cursor
) return *cursor
++;
66 for (int i
= index
;i
< size
; i
++)
67 if (bitset
->contains(i
)) { index
= i
+1; return i
; }
76 void copy_sparse (const FastBitSet
&);
77 void copy_dense (const FastBitSet
&);
78 void init_sparse (const FastBitSet
&);
79 void init_dense (const FastBitSet
&);
80 void init_dense (const BitSet
&);
81 void create_sparse (int bit
);
82 Bool
add_sparse (int bit
);
83 Bool
find_sparse (int bit
) const;
84 void basic_sparse_to_dense ();
85 void sparse_to_dense ();
88 inline FastBitSet(Mem
& m
, int number_of_bits
);
89 inline FastBitSet(const FastBitSet
& s
);
91 inline int size () const { return capacity
; }
92 inline Bool
contains (int bit
) const;
93 inline Bool
operator[] (int bit
) const;
95 inline void add (int bit
);
96 inline int first_bit () const;
98 void Union (const FastBitSet
&);
99 inline FastBitSet
& operator = (const FastBitSet
&);
101 friend ostream
& operator << (ostream
&, const FastBitSet
&);
102 inline friend unsigned int hash (const FastBitSet
*);
103 inline friend Bool
equal (const FastBitSet
*, const FastBitSet
*);
106 //////////////////////////////////////////////////////////////////////////////
108 // Inlined member functions.
110 //////////////////////////////////////////////////////////////////////////////
111 inline FastBitSet::Iter::Iter(const FastBitSet
& s
)
113 { case EMPTY
: tmp
[0] = -1; cursor
= tmp
; break;
114 case SINGLETON
: tmp
[0] = s
.one_bit
; tmp
[1] = -1; cursor
= tmp
;
116 case SPARSE
: cursor
= s
.sparse_set
; break;
117 case DENSE
: cursor
= 0; bitset
= s
.dense_set
; index
= 0;
118 size
= bitset
->size();
123 inline FastBitSet::FastBitSet(Mem
& m
, int number_of_bits
)
126 capacity(number_of_bits
),
127 sparse_set(0), dense_set(0)
130 inline FastBitSet::FastBitSet(const FastBitSet
& s
)
131 : mem(s
.mem
), capacity(s
.capacity
), sparse_set(0), dense_set(0)
132 { switch (kind
= s
.kind
)
133 { case SINGLETON
: one_bit
= s
.one_bit
; break;
134 case SPARSE
: init_sparse(s
); break;
135 case DENSE
: init_dense(s
); break;
140 inline FastBitSet
& FastBitSet::operator = (const FastBitSet
& s
)
141 { if (kind
== s
.kind
)
143 { case SINGLETON
: one_bit
= s
.one_bit
; break;
144 case SPARSE
: copy_sparse(s
); break;
145 case DENSE
: copy_dense(s
); break;
149 { switch (kind
= s
.kind
)
150 { case SINGLETON
: one_bit
= s
.one_bit
; break;
151 case SPARSE
: init_sparse(s
); break;
152 case DENSE
: init_dense(s
); break;
159 inline Bool
FastBitSet::contains (int bit
) const
161 { case EMPTY
: return false;
162 case SINGLETON
: return bit
== one_bit
;
163 case SPARSE
: return find_sparse(bit
);
164 default: return dense_set
->contains(bit
);
168 inline Bool
FastBitSet::operator[] (int bit
) const { return contains(bit
); }
170 inline void FastBitSet::add (int bit
)
172 { case EMPTY
: { kind
= SINGLETON
; one_bit
= bit
; }
173 case SINGLETON
: if (bit
!= one_bit
) create_sparse(bit
);
175 case SPARSE
: add_sparse(bit
); break;
176 default: dense_set
->add(bit
); break;
180 inline void FastBitSet::clear () { kind
= EMPTY
; }
182 inline unsigned hash (const FastBitSet
* set
)
184 { case FastBitSet::EMPTY
: return 257;
185 case FastBitSet::SINGLETON
: return 8 * set
->one_bit
;
186 case FastBitSet::SPARSE
:
187 { unsigned int h
= 0;
188 for (const short * p
= set
->sparse_set
; *p
>= 0; p
++)
192 default: return hash(set
->dense_set
);
196 inline Bool
equal (const FastBitSet
* a
, const FastBitSet
* b
)
197 { if (a
->kind
!= b
->kind
) return false;
199 { case FastBitSet::EMPTY
: return true;
200 case FastBitSet::SINGLETON
: return a
->one_bit
== b
->one_bit
;
201 case FastBitSet::SPARSE
:
202 { const short * p
, * q
;
203 for (p
= a
->sparse_set
, q
= b
->sparse_set
; ; p
++, q
++)
204 { if (*p
!= *q
) return false;
205 if (*p
< 0) return true;
209 default: return equal(a
->dense_set
, b
->dense_set
);
213 inline int FastBitSet::first_bit () const
215 { case SINGLETON
: return one_bit
;
216 case SPARSE
: return sparse_set
[0];
218 { for (int i
= 0, j
= dense_set
->size(); i
< j
; i
++)
219 if (dense_set
->contains(i
)) return i
;
223 return 32767*65536; // not found
226 //////////////////////////////////////////////////////////////////////////////
230 //////////////////////////////////////////////////////////////////////////////
231 inline void FastBitSet::Union (const FastBitSet
& f
)
232 { if (this == &f
) return;
234 { case EMPTY
: *this = f
; break;
237 { case SINGLETON
: if (one_bit
!= f
.one_bit
) create_sparse(f
.one_bit
);
239 case SPARSE
: { int b
= one_bit
; init_sparse(f
); add_sparse(b
);
241 case DENSE
: { int b
= one_bit
; init_dense(f
); dense_set
->add(b
);
248 { case SINGLETON
: add_sparse(f
.one_bit
); break;
251 short buf
[MAX_SPARSE
*3];
252 const short * p
= sparse_set
, * q
= f
.sparse_set
;
255 { if (*p
< 0) { while (*q
>= 0) *r
++ = *q
++; goto DONE
; }
256 if (*q
< 0) { while (*p
>= 0) *r
++ = *p
++; goto DONE
; }
257 if (*p
== *q
) { *r
++ = *p
++; q
++; }
258 else if (*p
< *q
) { *r
++ = *p
++; }
259 else { *r
++ = *q
++; }
263 if (count
>= MAX_SPARSE
)
265 for (const short * pp
= f
.sparse_set
; *pp
>= 0; pp
++)
269 memcpy(sparse_set
,buf
,sizeof(short)*(count
+1));
273 sparse_to_dense(); dense_set
->Union(*f
.dense_set
); break;
279 { case SINGLETON
: dense_set
->add(f
.one_bit
); break;
281 { for (const short * p
= f
.sparse_set
; *p
>= 0; p
++)
284 case DENSE
: dense_set
->Union(*f
.dense_set
); break;