roaring 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e21e62ddcac0d57cf83948329add1ead73e1299adc691b57dd940e7e5ca5306
4
- data.tar.gz: 1367042b6b8d27c24f9e124cf8c081bc18aa153e4431cb6339181c65904dbb68
3
+ metadata.gz: dc33ef0434903a23cc016fc7b1d31250280c96efd5e94ddbff4b8fa4f0977b73
4
+ data.tar.gz: 67b0b48a4b7dd2868977af10de721eba00e6c3aa08f222f1d3866a5003be5218
5
5
  SHA512:
6
- metadata.gz: 3b94ccd487a8b5e28b6130e25a759f4ab1d226670cb30063cede4c5815a19c69481a5a5f7bbfafc6ebbca6e55fdf6e85166e63f0c5fe13a82bfeaba3d107ec7d
7
- data.tar.gz: 9735a5df2fff46c07e917fc4cbd421fbff2bcca9304cf0da3f70c9f9e0ea12ed54447280b7a17b18f9d5a43a0f178f2d6fd840d5017dc80494b1f7add81ee242
6
+ metadata.gz: 2159681201c2f83fadc8d01fd2ddc1bedb7bcbc7828d955f6bf2c9ea8168fdce066f3f653cc7cfe935342f1bf126c895d09fd1f28296395e5f08331bf71807b2
7
+ data.tar.gz: 3d9bbdaecd48f645370d3bf116e00e457d878a6dce95be1b59c412088c969f4df09a4360897be8931eb2a94f44360c6cd3887abdffca56d6e784c71b0fa21307
data/.yardopts ADDED
@@ -0,0 +1 @@
1
+ --embed-mixins --no-private
data/Gemfile CHANGED
@@ -11,3 +11,6 @@ gem "rake-compiler"
11
11
  gem "debug"
12
12
 
13
13
  gem "minitest", "~> 5.0"
14
+
15
+ gem "yard"
16
+ gem "benchmark-ips"
data/Gemfile.lock CHANGED
@@ -6,6 +6,7 @@ PATH
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
+ benchmark-ips (2.13.0)
9
10
  debug (1.6.2)
10
11
  irb (>= 1.3.6)
11
12
  reline (>= 0.3.1)
@@ -23,17 +24,23 @@ GEM
23
24
  reline (0.3.1)
24
25
  io-console (~> 0.5)
25
26
  singleton (0.1.1)
27
+ yard (0.9.36)
26
28
 
27
29
  PLATFORMS
30
+ arm64-darwin-23
31
+ arm64-darwin-24
32
+ ruby
28
33
  x86_64-linux
29
34
 
30
35
  DEPENDENCIES
36
+ benchmark-ips
31
37
  debug
32
38
  minitest (~> 5.0)
33
39
  prime
34
40
  rake (~> 13.0)
35
41
  rake-compiler
36
42
  roaring!
43
+ yard
37
44
 
38
45
  BUNDLED WITH
39
46
  2.3.4
data/README.md CHANGED
@@ -1,9 +1,6 @@
1
1
  # Roaring
2
2
 
3
- A Ruby wrapper for CRoaring (a C/C++ implementation at https://github.com/RoaringBitmap/CRoaring)
4
-
5
- Roaring Bitmaps are a compressed bitmap/bitset format/library.
6
- More information and papers can be found at https://roaringbitmap.org/
3
+ [Roaring Bitmaps](http://www.roaringbitmap.org/about/) are a compressed bitmap/bitset format/library. Think of it like a `Set` which can only hold (32-bit or 64-bit) `Integer`s, with much lower memory use and supporting fast set operations.
7
4
 
8
5
  ## Installation
9
6
 
@@ -16,20 +13,26 @@ Install the gem and add to the application's Gemfile by executing:
16
13
  ``` ruby
17
14
  require "roaring"
18
15
 
19
- # Bitmaps can efficiently store a large range of 32-bit integers
20
- bitmap = Roaring::Bitmap[1, 2, 3, 999]
16
+ # Bitmap32 can efficiently store a large range of 32-bit integers
17
+ bitmap = Roaring::Bitmap32[1, 2, 3, 999]
21
18
  bitmap << (2**32 - 1)
22
19
 
20
+ # Bitmap64 can efficiently store a large range of 64-bit integers
21
+ bitmap = Roaring::Bitmap64[1, 2, 3, 999]
22
+ bitmap << (2**32 + 1)
23
+ bitmap << (2**64 - 1)
24
+
23
25
  # Element access
24
26
  bitmap.each { }
25
27
  bitmap.first # => 1
26
28
  bitmap.min # => 1
27
- bitmap.max # => 4294967295
28
- bitmap.last # => 4294967295
29
+ bitmap.max # => 18446744073709551615
30
+ bitmap.last # => 18446744073709551615
29
31
  bitmap[3] # => 999
32
+ bitmap.to_a # => [1, 2, 3, 999, 4294967297, 18446744073709551615]
30
33
 
31
- b1 = Roaring::Bitmap.new(200...500)
32
- b2 = Roaring::Bitmap.new(100...1000)
34
+ b1 = Roaring::Bitmap64.new(200...500)
35
+ b2 = Roaring::Bitmap64.new(100...1000)
33
36
 
34
37
  # Support common set operations
35
38
  (b1 & b2).size # => 300
@@ -41,12 +44,14 @@ b1 < b2 # => true
41
44
 
42
45
  # (De)Serialization (also available via Marshal#{dump,load})
43
46
  dump = bitmap.serialize
44
- loaded = Roaring::Bitmap.deserialize(dump)
47
+ loaded = Roaring::Bitmap64.deserialize(dump)
45
48
  loaded == bitmap # => true
46
49
  ```
47
50
 
48
51
  ## Development
49
52
 
53
+ This is a Ruby wrapper around [CRoaring](https://github.com/RoaringBitmap/CRoaring)
54
+
50
55
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
51
56
 
52
57
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
data/Rakefile CHANGED
@@ -3,6 +3,12 @@
3
3
  require "bundler/gem_tasks"
4
4
  require "rake/testtask"
5
5
 
6
+ require "yard"
7
+
8
+ YARD::Rake::YardocTask.new do |t|
9
+ t.files = ["lib/**/*.rb", "ext/**/*.c"]
10
+ end
11
+
6
12
  Rake::TestTask.new(:test) do |t|
7
13
  t.libs << "test"
8
14
  t.libs << "lib"
@@ -17,14 +23,13 @@ Rake::ExtensionTask.new("roaring") do |ext|
17
23
  ext.lib_dir = "lib/roaring"
18
24
  end
19
25
 
26
+ desc "Update vendored CRoaring library"
20
27
  task :update_roaring do
21
- require "open-uri"
22
-
23
- ["roaring.c", "roaring.h"].each do |filename|
24
- url = "https://github.com/RoaringBitmap/CRoaring/releases/latest/download/#{filename}"
25
- source = URI.open(url).read
26
- File.write("#{__dir__}/ext/roaring/#{filename}", source)
27
- end
28
+ rm_rf "tmp/CRoaring"
29
+ sh "git clone --depth=1 https://github.com/RoaringBitmap/CRoaring tmp/CRoaring"
30
+ sh "cd tmp/CRoaring && sh amalgamation.sh"
31
+ cp "tmp/CRoaring/roaring.c", "ext/roaring/roaring.c"
32
+ cp "tmp/CRoaring/roaring.h", "ext/roaring/roaring.h"
28
33
  end
29
34
 
30
35
  task default: %i[compile test]
data/benchmark/to_a.rb ADDED
@@ -0,0 +1,15 @@
1
+ require "benchmark/ips"
2
+ require "roaring"
3
+
4
+ small_bitmap = Roaring::Bitmap32[1,2,3,4]
5
+ large_bitmap = Roaring::Bitmap32[1..1000]
6
+
7
+ Benchmark.ips do |x|
8
+ x.report "small_bitmap.to_a" do
9
+ small_bitmap.to_a
10
+ end
11
+
12
+ x.report "large_bitmap.to_a" do
13
+ large_bitmap.to_a
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ require "benchmark/ips"
2
+ require "roaring"
3
+
4
+ small_bitmap = Roaring::Bitmap32[1,2,3,4]
5
+ large_bitmap = Roaring::Bitmap32[1..1000]
6
+
7
+ Benchmark.ips do |x|
8
+ x.report "small_bitmap.to_set" do
9
+ small_bitmap.to_set
10
+ end
11
+
12
+ x.report "large_bitmap.to_set" do
13
+ large_bitmap.to_set
14
+ end
15
+ end
@@ -48,6 +48,7 @@ static roaring_bitmap_t *get_bitmap(VALUE obj) {
48
48
  return bitmap;
49
49
  }
50
50
 
51
+ // Replaces the contents of `self` with another bitmap
51
52
  static VALUE rb_roaring32_replace(VALUE self, VALUE other) {
52
53
  roaring_bitmap_t *self_data = get_bitmap(self);
53
54
  roaring_bitmap_t *other_data = get_bitmap(other);
@@ -57,6 +58,7 @@ static VALUE rb_roaring32_replace(VALUE self, VALUE other) {
57
58
  return self;
58
59
  }
59
60
 
61
+ // @return [Integer] the number of elements in the bitmap
60
62
  static VALUE rb_roaring32_cardinality(VALUE self)
61
63
  {
62
64
  roaring_bitmap_t *data = get_bitmap(self);
@@ -64,6 +66,8 @@ static VALUE rb_roaring32_cardinality(VALUE self)
64
66
  return ULONG2NUM(cardinality);
65
67
  }
66
68
 
69
+ // Adds an element from the bitmap
70
+ // @param val [Integer] the value to add
67
71
  static VALUE rb_roaring32_add(VALUE self, VALUE val)
68
72
  {
69
73
  roaring_bitmap_t *data = get_bitmap(self);
@@ -73,6 +77,9 @@ static VALUE rb_roaring32_add(VALUE self, VALUE val)
73
77
  return self;
74
78
  }
75
79
 
80
+ // Adds an element from the bitmap
81
+ // @see {add}
82
+ // @return `self` if value was add, `nil` if value was already in the bitmap
76
83
  static VALUE rb_roaring32_add_p(VALUE self, VALUE val)
77
84
  {
78
85
  roaring_bitmap_t *data = get_bitmap(self);
@@ -81,6 +88,19 @@ static VALUE rb_roaring32_add_p(VALUE self, VALUE val)
81
88
  return roaring_bitmap_add_checked(data, num) ? self : Qnil;
82
89
  }
83
90
 
91
+ static VALUE rb_roaring32_add_range_closed(VALUE self, VALUE minv, VALUE maxv)
92
+ {
93
+ roaring_bitmap_t *data = get_bitmap(self);
94
+
95
+ uint32_t min = NUM2UINT32(minv);
96
+ uint32_t max = NUM2UINT32(maxv);
97
+
98
+ roaring_bitmap_add_range_closed(data, min, max);
99
+
100
+ return self;
101
+ }
102
+
103
+ // Removes an element from the bitmap
84
104
  static VALUE rb_roaring32_remove(VALUE self, VALUE val)
85
105
  {
86
106
  roaring_bitmap_t *data = get_bitmap(self);
@@ -90,6 +110,10 @@ static VALUE rb_roaring32_remove(VALUE self, VALUE val)
90
110
  return self;
91
111
  }
92
112
 
113
+ // Removes an element from the bitmap
114
+ //
115
+ // @see {remove}
116
+ // @return [self,nil] `self` if value was removed, `nil` if the value wasn't in the bitmap
93
117
  static VALUE rb_roaring32_remove_p(VALUE self, VALUE val)
94
118
  {
95
119
  roaring_bitmap_t *data = get_bitmap(self);
@@ -98,6 +122,7 @@ static VALUE rb_roaring32_remove_p(VALUE self, VALUE val)
98
122
  return roaring_bitmap_remove_checked(data, num) ? self : Qnil;
99
123
  }
100
124
 
125
+ // @return [Boolean] `true` if the bitmap is contains `val`, otherwise `false`
101
126
  static VALUE rb_roaring32_include_p(VALUE self, VALUE val)
102
127
  {
103
128
  roaring_bitmap_t *data = get_bitmap(self);
@@ -106,12 +131,14 @@ static VALUE rb_roaring32_include_p(VALUE self, VALUE val)
106
131
  return RBOOL(roaring_bitmap_contains(data, num));
107
132
  }
108
133
 
134
+ // @return [Boolean] `true` if the bitmap is empty, otherwise `false`
109
135
  static VALUE rb_roaring32_empty_p(VALUE self)
110
136
  {
111
137
  roaring_bitmap_t *data = get_bitmap(self);
112
138
  return RBOOL(roaring_bitmap_is_empty(data));
113
139
  }
114
140
 
141
+ // Removes all elements from the bitmap
115
142
  static VALUE rb_roaring32_clear(VALUE self)
116
143
  {
117
144
  roaring_bitmap_t *data = get_bitmap(self);
@@ -124,6 +151,8 @@ bool rb_roaring32_each_i(uint32_t value, void *param) {
124
151
  return true; // iterate till the end
125
152
  }
126
153
 
154
+ // Iterates over every element in the bitmap
155
+ // @return [self]
127
156
  static VALUE rb_roaring32_each(VALUE self)
128
157
  {
129
158
  roaring_bitmap_t *data = get_bitmap(self);
@@ -131,6 +160,8 @@ static VALUE rb_roaring32_each(VALUE self)
131
160
  return self;
132
161
  }
133
162
 
163
+ // Find the nth smallest integer in the bitmap
164
+ // @return [Integer,nil] The nth integer in the bitmap, or `nil` if `rankv` is `>= cardinality`
134
165
  static VALUE rb_roaring32_aref(VALUE self, VALUE rankv)
135
166
  {
136
167
  roaring_bitmap_t *data = get_bitmap(self);
@@ -146,6 +177,8 @@ static VALUE rb_roaring32_aref(VALUE self, VALUE rankv)
146
177
  return self;
147
178
  }
148
179
 
180
+ // Find the smallest integer in the bitmap
181
+ // @return [Integer,nil] The smallest integer in the bitmap, or `nil` if it is empty
149
182
  static VALUE rb_roaring32_min(VALUE self)
150
183
  {
151
184
  roaring_bitmap_t *data = get_bitmap(self);
@@ -158,6 +191,8 @@ static VALUE rb_roaring32_min(VALUE self)
158
191
  }
159
192
  }
160
193
 
194
+ // Find the largest integer in the bitmap
195
+ // @return [Integer,nil] The largest integer in the bitmap, or `nil` if it is empty
161
196
  static VALUE rb_roaring32_max(VALUE self)
162
197
  {
163
198
  roaring_bitmap_t *data = get_bitmap(self);
@@ -170,12 +205,16 @@ static VALUE rb_roaring32_max(VALUE self)
170
205
  }
171
206
  }
172
207
 
208
+ // Attemps to internally optimize the representation of bitmap by finding runs, consecutive sequences of integers.
209
+ // @return [Boolean] whether the result has at least one run container
173
210
  static VALUE rb_roaring32_run_optimize(VALUE self)
174
211
  {
175
212
  roaring_bitmap_t *data = get_bitmap(self);
176
213
  return RBOOL(roaring_bitmap_run_optimize(data));
177
214
  }
178
215
 
216
+ // Serializes a bitmap into a string
217
+ // @return [string]
179
218
  static VALUE rb_roaring32_serialize(VALUE self)
180
219
  {
181
220
  roaring_bitmap_t *data = get_bitmap(self);
@@ -189,6 +228,8 @@ static VALUE rb_roaring32_serialize(VALUE self)
189
228
  return str;
190
229
  }
191
230
 
231
+ // Loads a previously serialized bitmap
232
+ // @return [Bitmap32]
192
233
  static VALUE rb_roaring32_deserialize(VALUE self, VALUE str)
193
234
  {
194
235
  roaring_bitmap_t *bitmap = roaring_bitmap_portable_deserialize_safe(RSTRING_PTR(str), RSTRING_LEN(str));
@@ -196,6 +237,40 @@ static VALUE rb_roaring32_deserialize(VALUE self, VALUE str)
196
237
  return TypedData_Wrap_Struct(cRoaringBitmap32, &roaring_type, bitmap);
197
238
  }
198
239
 
240
+ // Provides statistics about the internal layout of the bitmap
241
+ // @return [Hash]
242
+ static VALUE rb_roaring32_statistics(VALUE self)
243
+ {
244
+ roaring_bitmap_t *data = get_bitmap(self);
245
+
246
+ roaring_statistics_t stat;
247
+
248
+ roaring_bitmap_statistics(data, &stat);
249
+
250
+ VALUE ret = rb_hash_new();
251
+ #define ADD_STAT(name) \
252
+ rb_hash_aset(ret, rb_id2sym(rb_intern(#name)), ULL2NUM(stat.name))
253
+
254
+ ADD_STAT(n_containers);
255
+ ADD_STAT(n_array_containers);
256
+ ADD_STAT(n_run_containers);
257
+ ADD_STAT(n_bitset_containers);
258
+ ADD_STAT(n_values_array_containers);
259
+ ADD_STAT(n_values_run_containers);
260
+ ADD_STAT(n_values_bitset_containers);
261
+ ADD_STAT(n_bytes_array_containers);
262
+ ADD_STAT(n_bytes_run_containers);
263
+ ADD_STAT(n_bytes_bitset_containers);
264
+ ADD_STAT(max_value);
265
+ ADD_STAT(min_value);
266
+ // ADD_STAT(sum_value); // deprecated, skipped
267
+ ADD_STAT(cardinality);
268
+
269
+ #undef ADD_STAT
270
+
271
+ return ret;
272
+ }
273
+
199
274
  typedef roaring_bitmap_t *binary_func(const roaring_bitmap_t *, const roaring_bitmap_t *);
200
275
  static VALUE rb_roaring32_binary_op(VALUE self, VALUE other, binary_func func) {
201
276
  roaring_bitmap_t *self_data = get_bitmap(self);
@@ -206,6 +281,16 @@ static VALUE rb_roaring32_binary_op(VALUE self, VALUE other, binary_func func) {
206
281
  return TypedData_Wrap_Struct(cRoaringBitmap32, &roaring_type, result);
207
282
  }
208
283
 
284
+ typedef void binary_func_inplace(roaring_bitmap_t *, const roaring_bitmap_t *);
285
+ static VALUE rb_roaring32_binary_op_inplace(VALUE self, VALUE other, binary_func_inplace func) {
286
+ roaring_bitmap_t *self_data = get_bitmap(self);
287
+ roaring_bitmap_t *other_data = get_bitmap(other);
288
+
289
+ func(self_data, other_data);
290
+
291
+ return self;
292
+ }
293
+
209
294
  typedef bool binary_func_bool(const roaring_bitmap_t *, const roaring_bitmap_t *);
210
295
  static VALUE rb_roaring32_binary_op_bool(VALUE self, VALUE other, binary_func_bool func) {
211
296
  roaring_bitmap_t *self_data = get_bitmap(self);
@@ -215,42 +300,85 @@ static VALUE rb_roaring32_binary_op_bool(VALUE self, VALUE other, binary_func_bo
215
300
  return RBOOL(result);
216
301
  }
217
302
 
303
+ // Inplace version of {and}
304
+ // @return [self] the modified Bitmap
305
+ static VALUE rb_roaring32_and_inplace(VALUE self, VALUE other)
306
+ {
307
+ return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_and_inplace);
308
+ }
309
+
310
+ // Inplace version of {or}
311
+ // @return [self] the modified Bitmap
312
+ static VALUE rb_roaring32_or_inplace(VALUE self, VALUE other)
313
+ {
314
+ return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_or_inplace);
315
+ }
316
+
317
+ // Inplace version of {xor}
318
+ // @return [self] the modified Bitmap
319
+ static VALUE rb_roaring32_xor_inplace(VALUE self, VALUE other)
320
+ {
321
+ return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_xor_inplace);
322
+ }
218
323
 
324
+ // Inplace version of {andnot}
325
+ // @return [self] the modified Bitmap
326
+ static VALUE rb_roaring32_andnot_inplace(VALUE self, VALUE other)
327
+ {
328
+ return rb_roaring32_binary_op_inplace(self, other, roaring_bitmap_andnot_inplace);
329
+ }
330
+
331
+ // Computes the intersection between two bitmaps
332
+ // @return [Bitmap32] a new bitmap containing all elements in both `self` and `other`
219
333
  static VALUE rb_roaring32_and(VALUE self, VALUE other)
220
334
  {
221
335
  return rb_roaring32_binary_op(self, other, roaring_bitmap_and);
222
336
  }
223
337
 
338
+ // Computes the union between two bitmaps
339
+ // @return [Bitmap32] a new bitmap containing all elements in either `self` or `other`
224
340
  static VALUE rb_roaring32_or(VALUE self, VALUE other)
225
341
  {
226
342
  return rb_roaring32_binary_op(self, other, roaring_bitmap_or);
227
343
  }
228
344
 
345
+ // Computes the exclusive or between two bitmaps
346
+ // @return [Bitmap32] a new bitmap containing all elements in one of `self` or `other`, but not both
229
347
  static VALUE rb_roaring32_xor(VALUE self, VALUE other)
230
348
  {
231
349
  return rb_roaring32_binary_op(self, other, roaring_bitmap_xor);
232
350
  }
233
351
 
352
+ // Computes the difference between two bitmaps
353
+ // @return [Bitmap32] a new bitmap containing all elements in `self`, but not in `other`
234
354
  static VALUE rb_roaring32_andnot(VALUE self, VALUE other)
235
355
  {
236
356
  return rb_roaring32_binary_op(self, other, roaring_bitmap_andnot);
237
357
  }
238
358
 
359
+ // Compare equality between two bitmaps
360
+ // @return [Boolean] `true` if both bitmaps contain all the same elements, otherwise `false`
239
361
  static VALUE rb_roaring32_eq(VALUE self, VALUE other)
240
362
  {
241
363
  return rb_roaring32_binary_op_bool(self, other, roaring_bitmap_equals);
242
364
  }
243
365
 
366
+ // Check if `self` is a strict subset of `other`. A strict subset requires every element in `self` is also in `other`, but they aren't exactly equal.
367
+ // @return [Boolean] `true` if `self` is a strict subset of `other`, otherwise `false`
244
368
  static VALUE rb_roaring32_lt(VALUE self, VALUE other)
245
369
  {
246
370
  return rb_roaring32_binary_op_bool(self, other, roaring_bitmap_is_strict_subset);
247
371
  }
248
372
 
373
+ // Check if `self` is a (non-strict) subset of `other`. A subset requires that every element in `self` is also in `other`. They may be equal.
374
+ // @return [Boolean] `true` if `self` is a subset of `other`, otherwise `false`
249
375
  static VALUE rb_roaring32_lte(VALUE self, VALUE other)
250
376
  {
251
377
  return rb_roaring32_binary_op_bool(self, other, roaring_bitmap_is_subset);
252
378
  }
253
379
 
380
+ // Checks whether `self` intersects `other`
381
+ // @return [Boolean] `true` if `self` intersects `other`, otherwise `false`
254
382
  static VALUE rb_roaring32_intersect_p(VALUE self, VALUE other)
255
383
  {
256
384
  return rb_roaring32_binary_op_bool(self, other, roaring_bitmap_intersect);
@@ -267,17 +395,22 @@ rb_roaring32_init(void)
267
395
  rb_define_method(cRoaringBitmap32, "cardinality", rb_roaring32_cardinality, 0);
268
396
  rb_define_method(cRoaringBitmap32, "add", rb_roaring32_add, 1);
269
397
  rb_define_method(cRoaringBitmap32, "add?", rb_roaring32_add_p, 1);
270
- rb_define_method(cRoaringBitmap32, "<<", rb_roaring32_add, 1);
398
+ rb_define_method(cRoaringBitmap32, "add_range_closed", rb_roaring32_add_range_closed, 2);
271
399
  rb_define_method(cRoaringBitmap32, "remove", rb_roaring32_remove, 1);
272
400
  rb_define_method(cRoaringBitmap32, "remove?", rb_roaring32_remove_p, 1);
273
401
  rb_define_method(cRoaringBitmap32, "include?", rb_roaring32_include_p, 1);
274
402
  rb_define_method(cRoaringBitmap32, "each", rb_roaring32_each, 0);
275
403
  rb_define_method(cRoaringBitmap32, "[]", rb_roaring32_aref, 1);
276
404
 
277
- rb_define_method(cRoaringBitmap32, "&", rb_roaring32_and, 1);
278
- rb_define_method(cRoaringBitmap32, "|", rb_roaring32_or, 1);
279
- rb_define_method(cRoaringBitmap32, "^", rb_roaring32_xor, 1);
280
- rb_define_method(cRoaringBitmap32, "-", rb_roaring32_andnot, 1);
405
+ rb_define_method(cRoaringBitmap32, "and!", rb_roaring32_and_inplace, 1);
406
+ rb_define_method(cRoaringBitmap32, "or!", rb_roaring32_or_inplace, 1);
407
+ rb_define_method(cRoaringBitmap32, "xor!", rb_roaring32_xor_inplace, 1);
408
+ rb_define_method(cRoaringBitmap32, "andnot!", rb_roaring32_andnot_inplace, 1);
409
+
410
+ rb_define_method(cRoaringBitmap32, "and", rb_roaring32_and, 1);
411
+ rb_define_method(cRoaringBitmap32, "or", rb_roaring32_or, 1);
412
+ rb_define_method(cRoaringBitmap32, "xor", rb_roaring32_xor, 1);
413
+ rb_define_method(cRoaringBitmap32, "andnot", rb_roaring32_andnot, 1);
281
414
 
282
415
  rb_define_method(cRoaringBitmap32, "==", rb_roaring32_eq, 1);
283
416
  rb_define_method(cRoaringBitmap32, "<", rb_roaring32_lt, 1);
@@ -288,6 +421,7 @@ rb_roaring32_init(void)
288
421
  rb_define_method(cRoaringBitmap32, "max", rb_roaring32_max, 0);
289
422
 
290
423
  rb_define_method(cRoaringBitmap32, "run_optimize", rb_roaring32_run_optimize, 0);
424
+ rb_define_method(cRoaringBitmap32, "statistics", rb_roaring32_statistics, 0);
291
425
 
292
426
  rb_define_method(cRoaringBitmap32, "serialize", rb_roaring32_serialize, 0);
293
427
  rb_define_singleton_method(cRoaringBitmap32, "deserialize", rb_roaring32_deserialize, 1);
@@ -56,7 +56,7 @@ static VALUE rb_roaring64_replace(VALUE self, VALUE other) {
56
56
  // FIXME: Very likely a newer version of CRoaring will have
57
57
  //roaring64_bitmap_overwrite(self_data, other_data);
58
58
 
59
- roaring64_bitmap_remove_range_closed(self_data, 0, UINT64_MAX);
59
+ roaring64_bitmap_clear(self_data);
60
60
  roaring64_bitmap_or_inplace(self_data, other_data);
61
61
 
62
62
  return self;
@@ -86,6 +86,18 @@ static VALUE rb_roaring64_add_p(VALUE self, VALUE val)
86
86
  return roaring64_bitmap_add_checked(data, num) ? self : Qnil;
87
87
  }
88
88
 
89
+ static VALUE rb_roaring64_add_range_closed(VALUE self, VALUE minv, VALUE maxv)
90
+ {
91
+ roaring64_bitmap_t *data = get_bitmap(self);
92
+
93
+ uint64_t min = NUM2UINT64(minv);
94
+ uint64_t max = NUM2UINT64(maxv);
95
+
96
+ roaring64_bitmap_add_range_closed(data, min, max);
97
+
98
+ return self;
99
+ }
100
+
89
101
  static VALUE rb_roaring64_remove(VALUE self, VALUE val)
90
102
  {
91
103
  roaring64_bitmap_t *data = get_bitmap(self);
@@ -120,8 +132,7 @@ static VALUE rb_roaring64_empty_p(VALUE self)
120
132
  static VALUE rb_roaring64_clear(VALUE self)
121
133
  {
122
134
  roaring64_bitmap_t *data = get_bitmap(self);
123
- // roaring64_bitmap_clear(data); // Doesn't exist yet in 4.0.0
124
- roaring64_bitmap_remove_range_closed(data, 0, UINT64_MAX);
135
+ roaring64_bitmap_clear(data);
125
136
  return self;
126
137
  }
127
138
 
@@ -202,6 +213,38 @@ static VALUE rb_roaring64_deserialize(VALUE self, VALUE str)
202
213
  return TypedData_Wrap_Struct(cRoaringBitmap64, &roaring64_type, bitmap);
203
214
  }
204
215
 
216
+ static VALUE rb_roaring64_statistics(VALUE self)
217
+ {
218
+ roaring64_bitmap_t *data = get_bitmap(self);
219
+
220
+ roaring64_statistics_t stat;
221
+
222
+ roaring64_bitmap_statistics(data, &stat);
223
+
224
+ VALUE ret = rb_hash_new();
225
+ #define ADD_STAT(name) \
226
+ rb_hash_aset(ret, rb_id2sym(rb_intern(#name)), ULL2NUM(stat.name))
227
+
228
+ ADD_STAT(n_containers);
229
+ ADD_STAT(n_array_containers);
230
+ ADD_STAT(n_run_containers);
231
+ ADD_STAT(n_bitset_containers);
232
+ ADD_STAT(n_values_array_containers);
233
+ ADD_STAT(n_values_run_containers);
234
+ ADD_STAT(n_values_bitset_containers);
235
+ ADD_STAT(n_bytes_array_containers);
236
+ ADD_STAT(n_bytes_run_containers);
237
+ ADD_STAT(n_bytes_bitset_containers);
238
+ ADD_STAT(max_value);
239
+ ADD_STAT(min_value);
240
+ // ADD_STAT(sum_value); // deprecated, skipped
241
+ ADD_STAT(cardinality);
242
+
243
+ #undef ADD_STAT
244
+
245
+ return ret;
246
+ }
247
+
205
248
  typedef roaring64_bitmap_t *binary_func(const roaring64_bitmap_t *, const roaring64_bitmap_t *);
206
249
  static VALUE rb_roaring64_binary_op(VALUE self, VALUE other, binary_func func) {
207
250
  roaring64_bitmap_t *self_data = get_bitmap(self);
@@ -212,6 +255,16 @@ static VALUE rb_roaring64_binary_op(VALUE self, VALUE other, binary_func func) {
212
255
  return TypedData_Wrap_Struct(cRoaringBitmap64, &roaring64_type, result);
213
256
  }
214
257
 
258
+ typedef void binary_func_inplace(roaring64_bitmap_t *, const roaring64_bitmap_t *);
259
+ static VALUE rb_roaring64_binary_op_inplace(VALUE self, VALUE other, binary_func_inplace func) {
260
+ roaring64_bitmap_t *self_data = get_bitmap(self);
261
+ roaring64_bitmap_t *other_data = get_bitmap(other);
262
+
263
+ func(self_data, other_data);
264
+
265
+ return self;
266
+ }
267
+
215
268
  typedef bool binary_func_bool(const roaring64_bitmap_t *, const roaring64_bitmap_t *);
216
269
  static VALUE rb_roaring64_binary_op_bool(VALUE self, VALUE other, binary_func_bool func) {
217
270
  roaring64_bitmap_t *self_data = get_bitmap(self);
@@ -221,6 +274,25 @@ static VALUE rb_roaring64_binary_op_bool(VALUE self, VALUE other, binary_func_bo
221
274
  return RBOOL(result);
222
275
  }
223
276
 
277
+ static VALUE rb_roaring64_and_inplace(VALUE self, VALUE other)
278
+ {
279
+ return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_and_inplace);
280
+ }
281
+
282
+ static VALUE rb_roaring64_or_inplace(VALUE self, VALUE other)
283
+ {
284
+ return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_or_inplace);
285
+ }
286
+
287
+ static VALUE rb_roaring64_xor_inplace(VALUE self, VALUE other)
288
+ {
289
+ return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_xor_inplace);
290
+ }
291
+
292
+ static VALUE rb_roaring64_andnot_inplace(VALUE self, VALUE other)
293
+ {
294
+ return rb_roaring64_binary_op_inplace(self, other, roaring64_bitmap_andnot_inplace);
295
+ }
224
296
 
225
297
  static VALUE rb_roaring64_and(VALUE self, VALUE other)
226
298
  {
@@ -273,6 +345,7 @@ rb_roaring64_init(void)
273
345
  rb_define_method(cRoaringBitmap64, "cardinality", rb_roaring64_cardinality, 0);
274
346
  rb_define_method(cRoaringBitmap64, "add", rb_roaring64_add, 1);
275
347
  rb_define_method(cRoaringBitmap64, "add?", rb_roaring64_add_p, 1);
348
+ rb_define_method(cRoaringBitmap64, "add_range_closed", rb_roaring64_add_range_closed, 2);
276
349
  rb_define_method(cRoaringBitmap64, "<<", rb_roaring64_add, 1);
277
350
  rb_define_method(cRoaringBitmap64, "remove", rb_roaring64_remove, 1);
278
351
  rb_define_method(cRoaringBitmap64, "remove?", rb_roaring64_remove_p, 1);
@@ -280,10 +353,15 @@ rb_roaring64_init(void)
280
353
  rb_define_method(cRoaringBitmap64, "each", rb_roaring64_each, 0);
281
354
  rb_define_method(cRoaringBitmap64, "[]", rb_roaring64_aref, 1);
282
355
 
283
- rb_define_method(cRoaringBitmap64, "&", rb_roaring64_and, 1);
284
- rb_define_method(cRoaringBitmap64, "|", rb_roaring64_or, 1);
285
- rb_define_method(cRoaringBitmap64, "^", rb_roaring64_xor, 1);
286
- rb_define_method(cRoaringBitmap64, "-", rb_roaring64_andnot, 1);
356
+ rb_define_method(cRoaringBitmap64, "and!", rb_roaring64_and_inplace, 1);
357
+ rb_define_method(cRoaringBitmap64, "or!", rb_roaring64_or_inplace, 1);
358
+ rb_define_method(cRoaringBitmap64, "xor!", rb_roaring64_xor_inplace, 1);
359
+ rb_define_method(cRoaringBitmap64, "andnot!", rb_roaring64_andnot_inplace, 1);
360
+
361
+ rb_define_method(cRoaringBitmap64, "and", rb_roaring64_and, 1);
362
+ rb_define_method(cRoaringBitmap64, "or", rb_roaring64_or, 1);
363
+ rb_define_method(cRoaringBitmap64, "xor", rb_roaring64_xor, 1);
364
+ rb_define_method(cRoaringBitmap64, "andnot", rb_roaring64_andnot, 1);
287
365
 
288
366
  rb_define_method(cRoaringBitmap64, "==", rb_roaring64_eq, 1);
289
367
  rb_define_method(cRoaringBitmap64, "<", rb_roaring64_lt, 1);
@@ -294,6 +372,7 @@ rb_roaring64_init(void)
294
372
  rb_define_method(cRoaringBitmap64, "max", rb_roaring64_max, 0);
295
373
 
296
374
  rb_define_method(cRoaringBitmap64, "run_optimize", rb_roaring64_run_optimize, 0);
375
+ rb_define_method(cRoaringBitmap64, "statistics", rb_roaring64_statistics, 0);
297
376
 
298
377
  rb_define_method(cRoaringBitmap64, "serialize", rb_roaring64_serialize, 0);
299
378
  rb_define_singleton_method(cRoaringBitmap64, "deserialize", rb_roaring64_deserialize, 1);