Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions arrow/bitutil/bitmap_ops.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,26 @@ func alignedBitXorGo(left, right, out []byte) {
out[i] = left[i] ^ right[i]
}
}

func alignedBitXnorGo(left, right, out []byte) {
var (
nbytes = len(out)
i = 0
)
if nbytes > uint64SizeBytes {
// case where we have enough bytes to operate on words
leftWords := bytesToUint64(left[i:])
rightWords := bytesToUint64(right[i:])
outWords := bytesToUint64(out[i:])

for w := range outWords {
outWords[w] = ^(leftWords[w] ^ rightWords[w])
}

i += len(outWords) * uint64SizeBytes
}
// grab any remaining bytes that were fewer than a word
for ; i < nbytes; i++ {
out[i] = ^(left[i] ^ right[i])
}
}
13 changes: 13 additions & 0 deletions arrow/bitutil/bitmaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,11 @@ var (
opByte: func(l, r byte) byte { return l ^ r },
opAligned: alignedBitXorGo,
}
bitXnorOp = bitOp{
opWord: func(l, r uint64) uint64 { return ^(l ^ r) },
opByte: func(l, r byte) byte { return ^(l ^ r) },
opAligned: alignedBitXnorGo,
}
)

func alignedBitmapOp(op bitOp, left, right []byte, lOffset, rOffset int64, out []byte, outOffset int64, length int64) {
Expand Down Expand Up @@ -592,6 +597,14 @@ func BitmapXorAlloc(mem memory.Allocator, left, right []byte, lOffset, rOffset i
return BitmapOpAlloc(mem, bitXorOp, left, right, lOffset, rOffset, length, outOffset)
}

func BitmapXnor(left, right []byte, lOffset, rOffset int64, out []byte, outOffset int64, length int64) {
BitmapOp(bitXnorOp, left, right, lOffset, rOffset, out, outOffset, length)
}

func BitmapXnorAlloc(mem memory.Allocator, left, right []byte, lOffset, rOffset int64, length, outOffset int64) *memory.Buffer {
return BitmapOpAlloc(mem, bitXnorOp, left, right, lOffset, rOffset, length, outOffset)
}

func BitmapEquals(left, right []byte, lOffset, rOffset int64, length int64) bool {
if lOffset%8 == 0 && rOffset%8 == 0 {
// byte aligned, fast path, can use bytes.Equal (memcmp)
Expand Down
18 changes: 18 additions & 0 deletions arrow/bitutil/bitmaps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,24 @@ func (s *BitmapOpSuite) TestBitmapOr() {
})
}

func (s *BitmapOpSuite) TestBitmapXnor() {
op := bitmapOp{
noAlloc: bitutil.BitmapXnor,
alloc: bitutil.BitmapXnorAlloc,
}

leftBits := []int{0, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1}
rightBits := []int{0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0}
resultBits := []bool{true, false, true, false, false, false, true, false, false, true, false, false, false, false}

s.Run("aligned", func() {
s.testAligned(op, leftBits, rightBits, resultBits)
})
s.Run("unaligned", func() {
s.testUnaligned(op, leftBits, rightBits, resultBits)
})
}

func TestBitmapOps(t *testing.T) {
suite.Run(t, new(BitmapOpSuite))
}
Expand Down
10 changes: 6 additions & 4 deletions arrow/compute/internal/kernels/scalar_comparisons.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ import (

type binaryKernel func(left, right, out []byte, offset int)

type cmpFn[LeftT, RightT arrow.FixedWidthType] func([]LeftT, []RightT, []uint32)
type cmpScalarLeft[LeftT, RightT arrow.FixedWidthType] func(LeftT, []RightT, []uint32)
type cmpScalarRight[LeftT, RightT arrow.FixedWidthType] func([]LeftT, RightT, []uint32)
type (
cmpFn[LeftT, RightT arrow.FixedWidthType] func([]LeftT, []RightT, []uint32)
cmpScalarLeft[LeftT, RightT arrow.FixedWidthType] func(LeftT, []RightT, []uint32)
cmpScalarRight[LeftT, RightT arrow.FixedWidthType] func([]LeftT, RightT, []uint32)
)

type cmpOp[T arrow.FixedWidthType] struct {
arrArr cmpFn[T, T]
Expand Down Expand Up @@ -589,7 +591,7 @@ func compareTimestampKernel(ty exec.InputType, op CompareOperator) exec.ScalarKe
var (
boolEQ = binaryBoolOps{
arrArr: func(_ *exec.KernelCtx, lhs, rhs, out bitutil.Bitmap) error {
bitutil.BitmapAnd(lhs.Data, rhs.Data, lhs.Offset, rhs.Offset, out.Data, out.Offset, out.Len)
bitutil.BitmapXnor(lhs.Data, rhs.Data, lhs.Offset, rhs.Offset, out.Data, out.Offset, out.Len)
Comment thread
Dhruvit96 marked this conversation as resolved.
return nil
},
arrScalar: func(_ *exec.KernelCtx, lhs bitutil.Bitmap, rhs bool, out bitutil.Bitmap) error {
Expand Down
15 changes: 15 additions & 0 deletions arrow/compute/scalar_compare_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,20 @@ func simpleArrArrCompare[T arrow.NumericType | string](mem memory.Allocator, op
return compute.NewDatum(result)
}

type BooleanCompareSuite struct {
CompareSuite
}

func (b *BooleanCompareSuite) TestBooleanBasics() {
var (
example1JSON = `[true, false, true, false]`
example2JSON = `[true, false, false, true]`
)

b.validateCompare(kernels.CmpEQ, arrow.FixedWidthTypes.Boolean, example1JSON, example2JSON, `[true, true, false, false]`)
b.validateCompare(kernels.CmpNE, arrow.FixedWidthTypes.Boolean, example1JSON, example2JSON, `[false, false, true, true]`)
}

type NumericCompareSuite[T arrow.NumericType] struct {
CompareSuite
}
Expand Down Expand Up @@ -1224,6 +1238,7 @@ func (c *CompareStringSuite) TestRandomCompareArrayArray() {
}

func TestComparisons(t *testing.T) {
suite.Run(t, new(BooleanCompareSuite))
suite.Run(t, new(NumericCompareSuite[int8]))
suite.Run(t, new(NumericCompareSuite[int16]))
suite.Run(t, new(NumericCompareSuite[int32]))
Expand Down
Loading