@@ -8,10 +8,10 @@ import (
88)
99
1010const (
11- bpw = 64 // bits per word
12- maxw = 1 << bpw - 1 // maximum value of a word
13- shift = 6 // 1<<6 == 64, to be used as multiplier/divisor by 64
14- div64rem = 63 // remainder of division by 64 when n&div64rem is used
11+ bpw = 64 // bits per word
12+ maxw uint64 = 1 << bpw - 1 // maximum value of a word
13+ shift = 6 // 1<<6 == 64, to be used as multiplier/divisor by 64
14+ div64rem = 63 // remainder of division by 64 when n&div64rem is used
1515)
1616
1717// Word is a convenience alias.
@@ -374,8 +374,31 @@ func And(s1, s2 BitSet) BitSet {
374374// And keeps only bits set in both *bs and other.
375375func (bs * BitSet ) And (other BitSet ) {
376376 minLen := min (len (* bs ), len (other ))
377- for i := 0 ; i < minLen ; i ++ {
378- (* bs )[i ] &= other [i ]
377+ if minLen < 8 {
378+ for i := 0 ; i < minLen ; i ++ {
379+ (* bs )[i ] &= other [i ]
380+ }
381+ for i := minLen ; i < len (* bs ); i ++ {
382+ (* bs )[i ] = 0
383+ }
384+ bs .trim ()
385+ return
386+ }
387+
388+ b := (* bs )[:minLen ]
389+ o := other [:minLen ]
390+ for ; len (o ) > 7 ; b , o = b [8 :], o [8 :] {
391+ b [0 ] &= o [0 ]
392+ b [1 ] &= o [1 ]
393+ b [2 ] &= o [2 ]
394+ b [3 ] &= o [3 ]
395+ b [4 ] &= o [4 ]
396+ b [5 ] &= o [5 ]
397+ b [6 ] &= o [6 ]
398+ b [7 ] &= o [7 ]
399+ }
400+ for i := range o {
401+ b [i ] &= o [i ]
379402 }
380403 for i := minLen ; i < len (* bs ); i ++ {
381404 (* bs )[i ] = 0
@@ -430,8 +453,28 @@ func (bs *BitSet) Or(other BitSet) {
430453 if len (other ) > len (* bs ) {
431454 bs .resize (len (other ))
432455 }
433- for i := 0 ; i < len (other ); i ++ {
434- (* bs )[i ] |= other [i ]
456+ if len (other ) < 8 {
457+ for i := range other {
458+ (* bs )[i ] |= other [i ]
459+ }
460+ bs .trim ()
461+ return
462+ }
463+
464+ b := * bs
465+ o := other
466+ for ; len (o ) > 7 ; b , o = b [8 :], o [8 :] {
467+ b [0 ] |= o [0 ]
468+ b [1 ] |= o [1 ]
469+ b [2 ] |= o [2 ]
470+ b [3 ] |= o [3 ]
471+ b [4 ] |= o [4 ]
472+ b [5 ] |= o [5 ]
473+ b [6 ] |= o [6 ]
474+ b [7 ] |= o [7 ]
475+ }
476+ for i := range o {
477+ b [i ] |= o [i ]
435478 }
436479 bs .trim ()
437480}
@@ -520,8 +563,28 @@ func AndNot(s1, s2 BitSet) BitSet {
520563// AndNot removes bits that are set in other from *bs.
521564func (bs * BitSet ) AndNot (other BitSet ) {
522565 minLen := min (len (* bs ), len (other ))
523- for i := 0 ; i < minLen ; i ++ {
524- (* bs )[i ] &^= other [i ]
566+ if minLen < 8 {
567+ for i := 0 ; i < minLen ; i ++ {
568+ (* bs )[i ] &^= other [i ]
569+ }
570+ bs .trim ()
571+ return
572+ }
573+
574+ b := (* bs )[:minLen ]
575+ o := other [:minLen ]
576+ for ; len (o ) > 7 ; b , o = b [8 :], o [8 :] {
577+ b [0 ] &^= o [0 ]
578+ b [1 ] &^= o [1 ]
579+ b [2 ] &^= o [2 ]
580+ b [3 ] &^= o [3 ]
581+ b [4 ] &^= o [4 ]
582+ b [5 ] &^= o [5 ]
583+ b [6 ] &^= o [6 ]
584+ b [7 ] &^= o [7 ]
585+ }
586+ for i := range o {
587+ b [i ] &^= o [i ]
525588 }
526589 bs .trim ()
527590}
0 commit comments