@@ -19,6 +19,20 @@ use bitslice::{bitwise, Union, Subtract, Intersect};
19
19
use indexed_vec:: Idx ;
20
20
use rustc_serialize;
21
21
22
+ /// This is implemented by all the index sets so that IdxSet::union() can be
23
+ /// passed any type of index set.
24
+ pub trait UnionIntoIdxSet < T : Idx > {
25
+ // Performs `other = other | self`.
26
+ fn union_into ( & self , other : & mut IdxSet < T > ) -> bool ;
27
+ }
28
+
29
+ /// This is implemented by all the index sets so that IdxSet::subtract() can be
30
+ /// passed any type of index set.
31
+ pub trait SubtractFromIdxSet < T : Idx > {
32
+ // Performs `other = other - self`.
33
+ fn subtract_from ( & self , other : & mut IdxSet < T > ) -> bool ;
34
+ }
35
+
22
36
/// Represents a set of some element type E, where each E is identified by some
23
37
/// unique index type `T`.
24
38
///
@@ -68,34 +82,34 @@ impl<T: Idx> fmt::Debug for IdxSet<T> {
68
82
}
69
83
70
84
impl < T : Idx > IdxSet < T > {
71
- fn new ( init : Word , universe_size : usize ) -> Self {
72
- let num_words = ( universe_size + ( BITS_PER_WORD - 1 ) ) / BITS_PER_WORD ;
85
+ fn new ( init : Word , domain_size : usize ) -> Self {
86
+ let num_words = ( domain_size + ( BITS_PER_WORD - 1 ) ) / BITS_PER_WORD ;
73
87
IdxSet {
74
88
_pd : Default :: default ( ) ,
75
89
bits : vec ! [ init; num_words] ,
76
90
}
77
91
}
78
92
79
- /// Creates set holding every element whose index falls in range 0..universe_size .
80
- pub fn new_filled ( universe_size : usize ) -> Self {
81
- let mut result = Self :: new ( !0 , universe_size ) ;
82
- result. trim_to ( universe_size ) ;
93
+ /// Creates set holding every element whose index falls in range 0..domain_size .
94
+ pub fn new_filled ( domain_size : usize ) -> Self {
95
+ let mut result = Self :: new ( !0 , domain_size ) ;
96
+ result. trim_to ( domain_size ) ;
83
97
result
84
98
}
85
99
86
100
/// Creates set holding no elements.
87
- pub fn new_empty ( universe_size : usize ) -> Self {
88
- Self :: new ( 0 , universe_size )
101
+ pub fn new_empty ( domain_size : usize ) -> Self {
102
+ Self :: new ( 0 , domain_size )
89
103
}
90
104
91
105
/// Duplicates as a hybrid set.
92
106
pub fn to_hybrid ( & self ) -> HybridIdxSet < T > {
93
- // This universe_size may be slightly larger than the one specified
107
+ // This domain_size may be slightly larger than the one specified
94
108
// upon creation, due to rounding up to a whole word. That's ok.
95
- let universe_size = self . bits . len ( ) * BITS_PER_WORD ;
109
+ let domain_size = self . bits . len ( ) * BITS_PER_WORD ;
96
110
97
111
// Note: we currently don't bother trying to make a Sparse set.
98
- HybridIdxSet :: Dense ( self . to_owned ( ) , universe_size )
112
+ HybridIdxSet :: Dense ( self . to_owned ( ) , domain_size )
99
113
}
100
114
101
115
/// Removes all elements
@@ -105,29 +119,29 @@ impl<T: Idx> IdxSet<T> {
105
119
}
106
120
}
107
121
108
- /// Sets all elements up to `universe_size `
109
- pub fn set_up_to ( & mut self , universe_size : usize ) {
122
+ /// Sets all elements up to `domain_size `
123
+ pub fn set_up_to ( & mut self , domain_size : usize ) {
110
124
for b in & mut self . bits {
111
125
* b = !0 ;
112
126
}
113
- self . trim_to ( universe_size ) ;
127
+ self . trim_to ( domain_size ) ;
114
128
}
115
129
116
- /// Clear all elements above `universe_size `.
117
- fn trim_to ( & mut self , universe_size : usize ) {
130
+ /// Clear all elements above `domain_size `.
131
+ fn trim_to ( & mut self , domain_size : usize ) {
118
132
// `trim_block` is the first block where some bits have
119
133
// to be cleared.
120
- let trim_block = universe_size / BITS_PER_WORD ;
134
+ let trim_block = domain_size / BITS_PER_WORD ;
121
135
122
136
// all the blocks above it have to be completely cleared.
123
137
if trim_block < self . bits . len ( ) {
124
138
for b in & mut self . bits [ trim_block+1 ..] {
125
139
* b = 0 ;
126
140
}
127
141
128
- // at that block, the `universe_size % BITS_PER_WORD` lsbs
142
+ // at that block, the `domain_size % BITS_PER_WORD` LSBs
129
143
// should remain.
130
- let remaining_bits = universe_size % BITS_PER_WORD ;
144
+ let remaining_bits = domain_size % BITS_PER_WORD ;
131
145
let mask = ( 1 <<remaining_bits) -1 ;
132
146
self . bits [ trim_block] &= mask;
133
147
}
@@ -164,48 +178,14 @@ impl<T: Idx> IdxSet<T> {
164
178
165
179
/// Set `self = self | other` and return true if `self` changed
166
180
/// (i.e., if new bits were added).
167
- pub fn union ( & mut self , other : & IdxSet < T > ) -> bool {
168
- bitwise ( self . words_mut ( ) , other. words ( ) , & Union )
169
- }
170
-
171
- /// Like `union()`, but takes a `SparseIdxSet` argument.
172
- fn union_sparse ( & mut self , other : & SparseIdxSet < T > ) -> bool {
173
- let mut changed = false ;
174
- for elem in other. iter ( ) {
175
- changed |= self . add ( & elem) ;
176
- }
177
- changed
178
- }
179
-
180
- /// Like `union()`, but takes a `HybridIdxSet` argument.
181
- pub fn union_hybrid ( & mut self , other : & HybridIdxSet < T > ) -> bool {
182
- match other {
183
- HybridIdxSet :: Sparse ( sparse, _) => self . union_sparse ( sparse) ,
184
- HybridIdxSet :: Dense ( dense, _) => self . union ( dense) ,
185
- }
181
+ pub fn union ( & mut self , other : & impl UnionIntoIdxSet < T > ) -> bool {
182
+ other. union_into ( self )
186
183
}
187
184
188
185
/// Set `self = self - other` and return true if `self` changed.
189
186
/// (i.e., if any bits were removed).
190
- pub fn subtract ( & mut self , other : & IdxSet < T > ) -> bool {
191
- bitwise ( self . words_mut ( ) , other. words ( ) , & Subtract )
192
- }
193
-
194
- /// Like `subtract()`, but takes a `SparseIdxSet` argument.
195
- fn subtract_sparse ( & mut self , other : & SparseIdxSet < T > ) -> bool {
196
- let mut changed = false ;
197
- for elem in other. iter ( ) {
198
- changed |= self . remove ( & elem) ;
199
- }
200
- changed
201
- }
202
-
203
- /// Like `subtract()`, but takes a `HybridIdxSet` argument.
204
- pub fn subtract_hybrid ( & mut self , other : & HybridIdxSet < T > ) -> bool {
205
- match other {
206
- HybridIdxSet :: Sparse ( sparse, _) => self . subtract_sparse ( sparse) ,
207
- HybridIdxSet :: Dense ( dense, _) => self . subtract ( dense) ,
208
- }
187
+ pub fn subtract ( & mut self , other : & impl SubtractFromIdxSet < T > ) -> bool {
188
+ other. subtract_from ( self )
209
189
}
210
190
211
191
/// Set `self = self & other` and return true if `self` changed.
@@ -223,6 +203,18 @@ impl<T: Idx> IdxSet<T> {
223
203
}
224
204
}
225
205
206
+ impl < T : Idx > UnionIntoIdxSet < T > for IdxSet < T > {
207
+ fn union_into ( & self , other : & mut IdxSet < T > ) -> bool {
208
+ bitwise ( other. words_mut ( ) , self . words ( ) , & Union )
209
+ }
210
+ }
211
+
212
+ impl < T : Idx > SubtractFromIdxSet < T > for IdxSet < T > {
213
+ fn subtract_from ( & self , other : & mut IdxSet < T > ) -> bool {
214
+ bitwise ( other. words_mut ( ) , self . words ( ) , & Subtract )
215
+ }
216
+ }
217
+
226
218
pub struct Iter < ' a , T : Idx > {
227
219
cur : Option < ( Word , usize ) > ,
228
220
iter : iter:: Enumerate < slice:: Iter < ' a , Word > > ,
@@ -293,8 +285,8 @@ impl<T: Idx> SparseIdxSet<T> {
293
285
}
294
286
}
295
287
296
- fn to_dense ( & self , universe_size : usize ) -> IdxSet < T > {
297
- let mut dense = IdxSet :: new_empty ( universe_size ) ;
288
+ fn to_dense ( & self , domain_size : usize ) -> IdxSet < T > {
289
+ let mut dense = IdxSet :: new_empty ( domain_size ) ;
298
290
for elem in self . 0 . iter ( ) {
299
291
dense. add ( elem) ;
300
292
}
@@ -308,6 +300,26 @@ impl<T: Idx> SparseIdxSet<T> {
308
300
}
309
301
}
310
302
303
+ impl < T : Idx > UnionIntoIdxSet < T > for SparseIdxSet < T > {
304
+ fn union_into ( & self , other : & mut IdxSet < T > ) -> bool {
305
+ let mut changed = false ;
306
+ for elem in self . iter ( ) {
307
+ changed |= other. add ( & elem) ;
308
+ }
309
+ changed
310
+ }
311
+ }
312
+
313
+ impl < T : Idx > SubtractFromIdxSet < T > for SparseIdxSet < T > {
314
+ fn subtract_from ( & self , other : & mut IdxSet < T > ) -> bool {
315
+ let mut changed = false ;
316
+ for elem in self . iter ( ) {
317
+ changed |= other. remove ( & elem) ;
318
+ }
319
+ changed
320
+ }
321
+ }
322
+
311
323
pub struct SparseIter < ' a , T : Idx > {
312
324
iter : slice:: Iter < ' a , T > ,
313
325
}
@@ -323,28 +335,24 @@ impl<'a, T: Idx> Iterator for SparseIter<'a, T> {
323
335
/// Like IdxSet, but with a hybrid representation: sparse when there are few
324
336
/// elements in the set, but dense when there are many. It's especially
325
337
/// efficient for sets that typically have a small number of elements, but a
326
- /// large `universe_size `, and are cleared frequently.
338
+ /// large `domain_size `, and are cleared frequently.
327
339
#[ derive( Clone , Debug ) ]
328
340
pub enum HybridIdxSet < T : Idx > {
329
341
Sparse ( SparseIdxSet < T > , usize ) ,
330
342
Dense ( IdxSet < T > , usize ) ,
331
343
}
332
344
333
345
impl < T : Idx > HybridIdxSet < T > {
334
- pub fn new_empty ( universe_size : usize ) -> Self {
335
- HybridIdxSet :: Sparse ( SparseIdxSet :: new ( ) , universe_size )
346
+ pub fn new_empty ( domain_size : usize ) -> Self {
347
+ HybridIdxSet :: Sparse ( SparseIdxSet :: new ( ) , domain_size )
336
348
}
337
349
338
- fn universe_size ( & mut self ) -> usize {
339
- match * self {
350
+ pub fn clear ( & mut self ) {
351
+ let domain_size = match * self {
340
352
HybridIdxSet :: Sparse ( _, size) => size,
341
353
HybridIdxSet :: Dense ( _, size) => size,
342
- }
343
- }
344
-
345
- pub fn clear ( & mut self ) {
346
- let universe_size = self . universe_size ( ) ;
347
- * self = HybridIdxSet :: new_empty ( universe_size) ;
354
+ } ;
355
+ * self = HybridIdxSet :: new_empty ( domain_size) ;
348
356
}
349
357
350
358
/// Returns true iff set `self` contains `elem`.
@@ -374,11 +382,11 @@ impl<T: Idx> HybridIdxSet<T> {
374
382
// appease the borrow checker.
375
383
let dummy = HybridIdxSet :: Sparse ( SparseIdxSet :: new ( ) , 0 ) ;
376
384
match mem:: replace ( self , dummy) {
377
- HybridIdxSet :: Sparse ( sparse, universe_size ) => {
378
- let mut dense = sparse. to_dense ( universe_size ) ;
385
+ HybridIdxSet :: Sparse ( sparse, domain_size ) => {
386
+ let mut dense = sparse. to_dense ( domain_size ) ;
379
387
let changed = dense. add ( elem) ;
380
388
assert ! ( changed) ;
381
- mem:: replace ( self , HybridIdxSet :: Dense ( dense, universe_size ) ) ;
389
+ mem:: replace ( self , HybridIdxSet :: Dense ( dense, domain_size ) ) ;
382
390
changed
383
391
}
384
392
_ => panic ! ( "impossible" ) ,
@@ -401,7 +409,7 @@ impl<T: Idx> HybridIdxSet<T> {
401
409
/// Converts to a dense set, consuming itself in the process.
402
410
pub fn to_dense ( self ) -> IdxSet < T > {
403
411
match self {
404
- HybridIdxSet :: Sparse ( sparse, universe_size ) => sparse. to_dense ( universe_size ) ,
412
+ HybridIdxSet :: Sparse ( sparse, domain_size ) => sparse. to_dense ( domain_size ) ,
405
413
HybridIdxSet :: Dense ( dense, _) => dense,
406
414
}
407
415
}
@@ -415,6 +423,24 @@ impl<T: Idx> HybridIdxSet<T> {
415
423
}
416
424
}
417
425
426
+ impl < T : Idx > UnionIntoIdxSet < T > for HybridIdxSet < T > {
427
+ fn union_into ( & self , other : & mut IdxSet < T > ) -> bool {
428
+ match self {
429
+ HybridIdxSet :: Sparse ( sparse, _) => sparse. union_into ( other) ,
430
+ HybridIdxSet :: Dense ( dense, _) => dense. union_into ( other) ,
431
+ }
432
+ }
433
+ }
434
+
435
+ impl < T : Idx > SubtractFromIdxSet < T > for HybridIdxSet < T > {
436
+ fn subtract_from ( & self , other : & mut IdxSet < T > ) -> bool {
437
+ match self {
438
+ HybridIdxSet :: Sparse ( sparse, _) => sparse. subtract_from ( other) ,
439
+ HybridIdxSet :: Dense ( dense, _) => dense. subtract_from ( other) ,
440
+ }
441
+ }
442
+ }
443
+
418
444
pub enum HybridIter < ' a , T : Idx > {
419
445
Sparse ( SparseIter < ' a , T > ) ,
420
446
Dense ( Iter < ' a , T > ) ,
0 commit comments