@@ -230,6 +230,7 @@ impl<T: Idx> BitSet<T> {
230230 bit_relations_inherent_impls ! { }
231231}
232232
233+ // dense REL dense
233234impl < T : Idx > BitRelations < BitSet < T > > for BitSet < T > {
234235 fn union ( & mut self , other : & BitSet < T > ) -> bool {
235236 assert_eq ! ( self . domain_size, other. domain_size) ;
@@ -285,6 +286,53 @@ fn dense_sparse_intersect<T: Idx>(
285286 ( sparse_copy, n != dense. count ( ) )
286287}
287288
289+ // hybrid REL dense
290+ impl < T : Idx > BitRelations < BitSet < T > > for HybridBitSet < T > {
291+ fn union ( & mut self , other : & BitSet < T > ) -> bool {
292+ match self {
293+ HybridBitSet :: Sparse ( sparse) => {
294+ // `self` is sparse and `other` is dense. To
295+ // merge them, we have two available strategies:
296+ // * Densify `self` then merge other
297+ // * Clone other then integrate bits from `self`
298+ // The second strategy requires dedicated method
299+ // since the usual `union` returns the wrong
300+ // result. In the dedicated case the computation
301+ // is slightly faster if the bits of the sparse
302+ // bitset map to only few words of the dense
303+ // representation, i.e. indices are near each
304+ // other.
305+ //
306+ // Benchmarking seems to suggest that the second
307+ // option is worth it.
308+ let mut new_dense = other. clone ( ) ;
309+ let changed = new_dense. reverse_union_sparse ( sparse) ;
310+ * self = HybridBitSet :: Dense ( new_dense) ;
311+ changed
312+ }
313+
314+ HybridBitSet :: Dense ( dense) => dense. union ( other) ,
315+ }
316+ }
317+
318+ fn subtract ( & mut self , other : & BitSet < T > ) -> bool {
319+ match self {
320+ HybridBitSet :: Sparse ( sparse) => {
321+ sequential_update ( |elem| sparse. remove ( elem) , other. iter ( ) )
322+ }
323+ HybridBitSet :: Dense ( dense) => dense. subtract ( other) ,
324+ }
325+ }
326+
327+ fn intersect ( & mut self , other : & BitSet < T > ) -> bool {
328+ match self {
329+ HybridBitSet :: Sparse ( sparse) => sparse_intersect ( sparse, |elem| other. contains ( * elem) ) ,
330+ HybridBitSet :: Dense ( dense) => dense. intersect ( other) ,
331+ }
332+ }
333+ }
334+
335+ // dense REL hybrid
288336impl < T : Idx > BitRelations < HybridBitSet < T > > for BitSet < T > {
289337 fn union ( & mut self , other : & HybridBitSet < T > ) -> bool {
290338 assert_eq ! ( self . domain_size, other. domain_size( ) ) ;
@@ -326,13 +374,14 @@ impl<T: Idx> BitRelations<HybridBitSet<T>> for BitSet<T> {
326374 }
327375}
328376
377+ // hybrid REL hybrid
329378impl < T : Idx > BitRelations < HybridBitSet < T > > for HybridBitSet < T > {
330379 fn union ( & mut self , other : & HybridBitSet < T > ) -> bool {
331380 assert_eq ! ( self . domain_size( ) , other. domain_size( ) ) ;
332381 match self {
333382 HybridBitSet :: Sparse ( self_sparse) => {
334383 match other {
335- HybridBitSet :: Sparse ( other_sparse ) => {
384+ HybridBitSet :: Sparse ( _ ) => {
336385 // Both sets are sparse. Add the elements in
337386 // `other_sparse` to `self` one at a time. This
338387 // may or may not cause `self` to be densified.
@@ -344,26 +393,7 @@ impl<T: Idx> BitRelations<HybridBitSet<T>> for HybridBitSet<T> {
344393 changed
345394 }
346395
347- HybridBitSet :: Dense ( other_dense) => {
348- // `self` is sparse and `other` is dense. To
349- // merge them, we have two available strategies:
350- // * Densify `self` then merge other
351- // * Clone other then integrate bits from `self`
352- // The second strategy requires dedicated method
353- // since the usual `union` returns the wrong
354- // result. In the dedicated case the computation
355- // is slightly faster if the bits of the sparse
356- // bitset map to only few words of the dense
357- // representation, i.e. indices are near each
358- // other.
359- //
360- // Benchmarking seems to suggest that the second
361- // option is worth it.
362- let mut new_dense = other_dense. clone ( ) ;
363- let changed = new_dense. reverse_union_sparse ( self_sparse) ;
364- * self = HybridBitSet :: Dense ( new_dense) ;
365- changed
366- }
396+ HybridBitSet :: Dense ( other_dense) => self . union ( other_dense) ,
367397 }
368398 }
369399
0 commit comments