Keep the _many primitives for equal-sized operands, fold only ragged ones

This commit is contained in:
dualfroz committed 2026-09-23 06:12:58 +02:00
1 parent 4b1c980512
commit 666c48ccf8
4 files changed
+87 -50

No files matched your search

+24 -32
View File
@@ -83,15 +83,13 @@ func (dst *Bitmap) Or(other Bitmap, extra ...Bitmap) {
case 0:
_or(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
default:
// _or_many uses one word count for every input, so it cannot union
// bitmaps of different lengths. Union each source over its own.
if len(other) > 0 {
_or(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
}
for i := range extra {
if len(extra[i]) > 0 {
_or(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&extra[i][0]), uint64(len(extra[i])))
}
// _or_many applies one word count to every input, so it only fits
// sources that share a length; ragged ones are folded in one by one.
if n := uniformLen(other, extra); n > 0 {
vx, _ := pointersOf(other, extra)
_or_many(unsafe.Pointer(&(*dst)[0]), vx, dimensionsOf(n, len(extra)+1))
} else {
foldEach(dst, _or, other, extra)
}
}
case isAVX512:
@@ -99,13 +97,11 @@ func (dst *Bitmap) Or(other Bitmap, extra ...Bitmap) {
case 0:
_or_avx512(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
default:
if len(other) > 0 {
_or_avx512(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
}
for i := range extra {
if len(extra[i]) > 0 {
_or_avx512(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&extra[i][0]), uint64(len(extra[i])))
}
if n := uniformLen(other, extra); n > 0 {
vx, _ := pointersOf(other, extra)
_or_many_avx512(unsafe.Pointer(&(*dst)[0]), vx, dimensionsOf(n, len(extra)+1))
} else {
foldEach(dst, _or_avx512, other, extra)
}
}
default:
@@ -127,15 +123,13 @@ func (dst *Bitmap) Xor(other Bitmap, extra ...Bitmap) {
case 0:
_xor(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
default:
// _xor_many uses one word count for every input, so it cannot combine
// bitmaps of different lengths. Fold in each source over its own.
if len(other) > 0 {
_xor(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
}
for i := range extra {
if len(extra[i]) > 0 {
_xor(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&extra[i][0]), uint64(len(extra[i])))
}
// _xor_many applies one word count to every input, so it only fits
// sources that share a length; ragged ones are folded in one by one.
if n := uniformLen(other, extra); n > 0 {
vx, _ := pointersOf(other, extra)
_xor_many(unsafe.Pointer(&(*dst)[0]), vx, dimensionsOf(n, len(extra)+1))
} else {
foldEach(dst, _xor, other, extra)
}
}
case isAVX512:
@@ -143,13 +137,11 @@ func (dst *Bitmap) Xor(other Bitmap, extra ...Bitmap) {
case 0:
_xor_avx512(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
default:
if len(other) > 0 {
_xor_avx512(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&other[0]), uint64(len(other)))
}
for i := range extra {
if len(extra[i]) > 0 {
_xor_avx512(unsafe.Pointer(&(*dst)[0]), unsafe.Pointer(&extra[i][0]), uint64(len(extra[i])))
}
if n := uniformLen(other, extra); n > 0 {
vx, _ := pointersOf(other, extra)
_xor_many_avx512(unsafe.Pointer(&(*dst)[0]), vx, dimensionsOf(n, len(extra)+1))
} else {
foldEach(dst, _xor_avx512, other, extra)
}
}
default: