Skip to content

Commit

Permalink
Add inplace versions of binary operations
Browse files Browse the repository at this point in the history
  • Loading branch information
jhawthorn committed Jun 26, 2024
1 parent 866987e commit 7775b4a
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 0 deletions.
34 changes: 34 additions & 0 deletions ext/roaring/bitmap32.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,16 @@ static VALUE rb_roaring32_binary_op(VALUE self, VALUE other, binary_func func) {
return TypedData_Wrap_Struct(cRoaringBitmap32, &roaring_type, result);
}

typedef void binary_func_inplace(roaring_bitmap_t *, const roaring_bitmap_t *);
static VALUE rb_roaring32_binary_op_inplace(VALUE self, VALUE other, binary_func_inplace func) {
roaring_bitmap_t *self_data = get_bitmap(self);
roaring_bitmap_t *other_data = get_bitmap(other);

func(self_data, other_data);

return self;
}

typedef bool binary_func_bool(const roaring_bitmap_t *, const roaring_bitmap_t *);
static VALUE rb_roaring32_binary_op_bool(VALUE self, VALUE other, binary_func_bool func) {
roaring_bitmap_t *self_data = get_bitmap(self);
Expand All @@ -247,6 +257,25 @@ static VALUE rb_roaring32_binary_op_bool(VALUE self, VALUE other, binary_func_bo
return RBOOL(result);
}

static VALUE rb_roaring32_and_inplace(VALUE self, VALUE other)
{
return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_and_inplace);
}

static VALUE rb_roaring32_or_inplace(VALUE self, VALUE other)
{
return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_or_inplace);
}

static VALUE rb_roaring32_xor_inplace(VALUE self, VALUE other)
{
return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_xor_inplace);
}

static VALUE rb_roaring32_andnot_inplace(VALUE self, VALUE other)
{
return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_andnot_inplace);
}

static VALUE rb_roaring32_and(VALUE self, VALUE other)
{
Expand Down Expand Up @@ -306,6 +335,11 @@ rb_roaring32_init(void)
rb_define_method(cRoaringBitmap32, "each", rb_roaring32_each, 0);
rb_define_method(cRoaringBitmap32, "[]", rb_roaring32_aref, 1);

rb_define_method(cRoaringBitmap32, "and!", rb_roaring32_and_inplace, 1);
rb_define_method(cRoaringBitmap32, "or!", rb_roaring32_or_inplace, 1);
rb_define_method(cRoaringBitmap32, "xor!", rb_roaring32_xor_inplace, 1);
rb_define_method(cRoaringBitmap32, "andnot!", rb_roaring32_andnot_inplace, 1);

rb_define_method(cRoaringBitmap32, "&", rb_roaring32_and, 1);
rb_define_method(cRoaringBitmap32, "|", rb_roaring32_or, 1);
rb_define_method(cRoaringBitmap32, "^", rb_roaring32_xor, 1);
Expand Down
34 changes: 34 additions & 0 deletions ext/roaring/bitmap64.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,16 @@ static VALUE rb_roaring64_binary_op(VALUE self, VALUE other, binary_func func) {
return TypedData_Wrap_Struct(cRoaringBitmap64, &roaring64_type, result);
}

typedef void binary_func_inplace(roaring64_bitmap_t *, const roaring64_bitmap_t *);
static VALUE rb_roaring64_binary_op_inplace(VALUE self, VALUE other, binary_func_inplace func) {
roaring64_bitmap_t *self_data = get_bitmap(self);
roaring64_bitmap_t *other_data = get_bitmap(other);

func(self_data, other_data);

return self;
}

typedef bool binary_func_bool(const roaring64_bitmap_t *, const roaring64_bitmap_t *);
static VALUE rb_roaring64_binary_op_bool(VALUE self, VALUE other, binary_func_bool func) {
roaring64_bitmap_t *self_data = get_bitmap(self);
Expand All @@ -252,6 +262,25 @@ static VALUE rb_roaring64_binary_op_bool(VALUE self, VALUE other, binary_func_bo
return RBOOL(result);
}

static VALUE rb_roaring64_and_inplace(VALUE self, VALUE other)
{
return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_and_inplace);
}

static VALUE rb_roaring64_or_inplace(VALUE self, VALUE other)
{
return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_or_inplace);
}

static VALUE rb_roaring64_xor_inplace(VALUE self, VALUE other)
{
return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_xor_inplace);
}

static VALUE rb_roaring64_andnot_inplace(VALUE self, VALUE other)
{
return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_andnot_inplace);
}

static VALUE rb_roaring64_and(VALUE self, VALUE other)
{
Expand Down Expand Up @@ -311,6 +340,11 @@ rb_roaring64_init(void)
rb_define_method(cRoaringBitmap64, "each", rb_roaring64_each, 0);
rb_define_method(cRoaringBitmap64, "[]", rb_roaring64_aref, 1);

rb_define_method(cRoaringBitmap64, "and!", rb_roaring64_and_inplace, 1);
rb_define_method(cRoaringBitmap64, "or!", rb_roaring64_or_inplace, 1);
rb_define_method(cRoaringBitmap64, "xor!", rb_roaring64_xor_inplace, 1);
rb_define_method(cRoaringBitmap64, "andnot!", rb_roaring64_andnot_inplace, 1);

rb_define_method(cRoaringBitmap64, "&", rb_roaring64_and, 1);
rb_define_method(cRoaringBitmap64, "|", rb_roaring64_or, 1);
rb_define_method(cRoaringBitmap64, "^", rb_roaring64_xor, 1);
Expand Down
36 changes: 36 additions & 0 deletions test/test_bitmaps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -229,27 +229,63 @@ def test_and
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1 & r2
refute_same r1, result
assert_equal [3, 4], result.to_a
end

def test_or
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1 | r2
refute_same r1, result
assert_equal [1, 2, 3, 4, 5, 6], result.to_a
end

def test_xor
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1 ^ r2
refute_same r1, result
assert_equal [1, 2, 5, 6], result.to_a
end

def test_difference
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1 - r2
refute_same r1, result
assert_equal [1, 2], result.to_a
end

def test_and_inplace
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1.and!(r2)
assert_same r1, result
assert_equal [3, 4], result.to_a
end

def test_or_inplace
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1.or!(r2)
assert_same r1, result
assert_equal [1, 2, 3, 4, 5, 6], result.to_a
end

def test_xor_inplace
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1.xor!(r2)
assert_same r1, result
assert_equal [1, 2, 5, 6], result.to_a
end

def test_difference_inplace
r1 = bitmap_class[1, 2, 3, 4]
r2 = bitmap_class[3, 4, 5, 6]
result = r1.andnot!(r2)
assert_same r1, result
assert_equal [1, 2], result.to_a
end

Expand Down

0 comments on commit 7775b4a

Please sign in to comment.