aerospike 2.24.0 → 2.25.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,388 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2022 Aerospike, Inc.
3
+ #
4
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
+ # license agreements.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License"); you may no
8
+ # use this file except in compliance with the License. You may obtain a copy of
9
+ # the License at http:#www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ module Aerospike
18
+ # Bit expression generator. See {@link Exp}.
19
+ #
20
+ # The bin expression argument in these methods can be a reference to a bin or the
21
+ # result of another expression. Expressions that modify bin values are only used
22
+ # for temporary expression evaluation and are not permanently applied to the bin.
23
+ # Bit modify expressions the blob bin's value.
24
+ #
25
+ # Offset orientation is left-to-right. Negative offsets are supported.
26
+ # If the offset is negative, the offset starts backwards from end of the bitmap.
27
+ # If an offset is out of bounds, a parameter error will be returned.
28
+ class Exp::Bit
29
+ # Create expression that resizes _byte[]_ to _byte_size_ according to _resize_flags_ (See {CDT::BitResizeFlags})
30
+ # and returns byte[].
31
+ #
32
+ # bin = [0b00000001, 0b01000010]
33
+ # byte_size = 4
34
+ # resize_flags = 0
35
+ # returns [0b00000001, 0b01000010, 0b00000000, 0b00000000]
36
+ #
37
+ # ==== Examples
38
+ # # Resize bin "a" and compare bit count
39
+ # Exp.eq(
40
+ # BitExp.count(Exp.val(0), Exp.val(3),
41
+ # BitExp.resize(BitPolicy.Default, Exp.val(4), 0, Exp.blobBin("a"))),
42
+ # Exp.val(2))
43
+ def self.resize(byte_size, resize_flags, bin, policy: CDT::BitPolicy::DEFAULT)
44
+ bytes = Exp.pack(nil, RESIZE, byte_size, policy.flags, resize_flags)
45
+ self.add_write(bin, bytes)
46
+ end
47
+
48
+ # Create expression that inserts value bytes into byte[] bin at byte_offset and returns byte[].
49
+ #
50
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
51
+ # byte_offset = 1
52
+ # value = [0b11111111, 0b11000111]
53
+ # bin result = [0b00000001, 0b11111111, 0b11000111, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
54
+ #
55
+ # ==== Examples
56
+ # # Insert bytes into bin "a" and compare bit count
57
+ # Exp.eq(
58
+ # BitExp.count(Exp.val(0), Exp.val(3),
59
+ # BitExp.insert(BitPolicy.Default, Exp.val(1), Exp.val(bytes), Exp.blobBin("a"))),
60
+ # Exp.val(2))
61
+ def self.insert(byte_offset, value, bin, policy: CDT::BitPolicy::DEFAULT)
62
+ bytes = Exp.pack(nil, INSERT, byte_offset, value, policy.flags)
63
+ self.add_write(bin, bytes)
64
+ end
65
+
66
+ # Create expression that removes bytes from byte[] bin at byte_offset for byte_size and returns byte[].
67
+ #
68
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
69
+ # byte_offset = 2
70
+ # byte_size = 3
71
+ # bin result = [0b00000001, 0b01000010]
72
+ #
73
+ # ==== Examples
74
+ # # Remove bytes from bin "a" and compare bit count
75
+ # Exp.eq(
76
+ # BitExp.count(Exp.val(0), Exp.val(3),
77
+ # BitExp.remove(BitPolicy.Default, Exp.val(2), Exp.val(3), Exp.blobBin("a"))),
78
+ # Exp.val(2))
79
+ def self.remove(byte_offset, byte_size, bin, policy: CDT::BitPolicy::DEFAULT)
80
+ bytes = Exp.pack(nil, REMOVE, byte_offset, byte_size, policy.flags)
81
+ self.add_write(bin, bytes)
82
+ end
83
+
84
+ # Create expression that sets value on byte[] bin at bit_offset for bit_size and returns byte[].
85
+ #
86
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
87
+ # bit_offset = 13
88
+ # bit_size = 3
89
+ # value = [0b11100000]
90
+ # bin result = [0b00000001, 0b01000111, 0b00000011, 0b00000100, 0b00000101]
91
+ #
92
+ # ==== Examples
93
+ # # Set bytes in bin "a" and compare bit count
94
+ # Exp.eq(
95
+ # BitExp.count(Exp.val(0), Exp.val(3),
96
+ # BitExp.set(BitPolicy.Default, Exp.val(13), Exp.val(3), Exp.val(bytes), Exp.blobBin("a"))),
97
+ # Exp.val(2))
98
+ def self.set(bit_offset, bit_size, value, bin, policy: CDT::BitPolicy::DEFAULT)
99
+ bytes = Exp.pack(nil, SET, bit_offset, bit_size, value, policy.flags)
100
+ self.add_write(bin, bytes)
101
+ end
102
+
103
+ # Create expression that performs bitwise "or" on value and byte[] bin at bit_offset for bit_size
104
+ # and returns byte[].
105
+ #
106
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
107
+ # bit_offset = 17
108
+ # bit_size = 6
109
+ # value = [0b10101000]
110
+ # bin result = [0b00000001, 0b01000010, 0b01010111, 0b00000100, 0b00000101]
111
+ #
112
+ def self.or(bit_offset, bit_size, value, bin, policy: CDT::BitPolicy::DEFAULT)
113
+ bytes = Exp.pack(nil, OR, bit_offset, bit_size, value, policy.flags)
114
+ self.add_write(bin, bytes)
115
+ end
116
+
117
+ # Create expression that performs bitwise "xor" on value and byte[] bin at bit_offset for bit_size
118
+ # and returns byte[].
119
+ #
120
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
121
+ # bit_offset = 17
122
+ # bit_size = 6
123
+ # value = [0b10101100]
124
+ # bin result = [0b00000001, 0b01000010, 0b01010101, 0b00000100, 0b00000101]
125
+ #
126
+ def self.xor(bit_offset, bit_size, value, bin, policy: CDT::BitPolicy::DEFAULT)
127
+ bytes = Exp.pack(nil, XOR, bit_offset, bit_size, value, policy.flags)
128
+ self.add_write(bin, bytes)
129
+ end
130
+
131
+ # Create expression that performs bitwise "and" on value and byte[] bin at bit_offset for bit_size
132
+ # and returns byte[].
133
+ #
134
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
135
+ # bit_offset = 23
136
+ # bit_size = 9
137
+ # value = [0b00111100, 0b10000000]
138
+ # bin result = [0b00000001, 0b01000010, 0b00000010, 0b00000000, 0b00000101]
139
+ #
140
+ def self.and(bit_offset, bit_size, value, bin, policy: CDT::BitPolicy::DEFAULT)
141
+ bytes = Exp.pack(nil, AND, bit_offset, bit_size, value, policy.flags)
142
+ self.add_write(bin, bytes)
143
+ end
144
+
145
+ # Create expression that negates byte[] bin starting at bit_offset for bit_size and returns byte[].
146
+ #
147
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
148
+ # bit_offset = 25
149
+ # bit_size = 6
150
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b01111010, 0b00000101]
151
+ #
152
+ def self.not(bit_offset, bit_size, bin, policy: CDT::BitPolicy::DEFAULT)
153
+ bytes = Exp.pack(nil, NOT, bit_offset, bit_size, policy.flags)
154
+ self.add_write(bin, bytes)
155
+ end
156
+
157
+ # Create expression that shifts left byte[] bin starting at bit_offset for bit_size and returns byte[].
158
+ #
159
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
160
+ # bit_offset = 32
161
+ # bit_size = 8
162
+ # shift = 3
163
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00101000]
164
+ #
165
+ def self.lshift(bit_offset, bit_size, shift, bin, policy: CDT::BitPolicy::DEFAULT)
166
+ bytes = Exp.pack(nil, LSHIFT, bit_offset, bit_size, shift, policy.flags)
167
+ self.add_write(bin, bytes)
168
+ end
169
+
170
+ # Create expression that shifts right byte[] bin starting at bit_offset for bit_size and returns byte[].
171
+ #
172
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
173
+ # bit_offset = 0
174
+ # bit_size = 9
175
+ # shift = 1
176
+ # bin result = [0b00000000, 0b11000010, 0b00000011, 0b00000100, 0b00000101]
177
+ #
178
+ def self.rshift(bit_offset, bit_size, shift, bin, policy: CDT::BitPolicy::DEFAULT)
179
+ bytes = Exp.pack(nil, RSHIFT, bit_offset, bit_size, shift, policy.flags)
180
+ self.add_write(bin, bytes)
181
+ end
182
+
183
+ # Create expression that adds value to byte[] bin starting at bit_offset for bit_size and returns byte[].
184
+ # BitSize must be <= 64. Signed indicates if bits should be treated as a signed number.
185
+ # If add overflows/underflows, {@link BitOverflowAction} is used.
186
+ #
187
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
188
+ # bit_offset = 24
189
+ # bit_size = 16
190
+ # value = 128
191
+ # signed = false
192
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b10000101]
193
+ #
194
+ def self.add(bit_offset, bit_size, value, signed, bit_overflow_action, bin, policy: CDT::BitPolicy::DEFAULT)
195
+ bytes = self.pack_math(ADD, policy, bit_offset, bit_size, value, signed, bit_overflow_action)
196
+ self.add_write(bin, bytes)
197
+ end
198
+
199
+ # Create expression that subtracts value from byte[] bin starting at bit_offset for bit_size and returns byte[].
200
+ # BitSize must be <= 64. Signed indicates if bits should be treated as a signed number.
201
+ # If add overflows/underflows, {@link BitOverflowAction} is used.
202
+ #
203
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
204
+ # bit_offset = 24
205
+ # bit_size = 16
206
+ # value = 128
207
+ # signed = false
208
+ # bin result = [0b00000001, 0b01000010, 0b00000011, 0b0000011, 0b10000101]
209
+ #
210
+ def self.subtract(bit_offset, bit_size, value, signed, bit_overflow_action, bin, policy: CDT::BitPolicy::DEFAULT)
211
+ bytes = self.pack_math(SUBTRACT, policy, bit_offset, bit_size, value, signed, bit_overflow_action)
212
+ self.add_write(bin, bytes)
213
+ end
214
+
215
+ # Create expression that sets value to byte[] bin starting at bit_offset for bit_size and returns byte[].
216
+ # BitSize must be <= 64.
217
+ #
218
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
219
+ # bit_offset = 1
220
+ # bit_size = 8
221
+ # value = 127
222
+ # bin result = [0b00111111, 0b11000010, 0b00000011, 0b0000100, 0b00000101]
223
+ #
224
+ def self.set_int(bit_offset, bit_size, value, bin, policy: CDT::BitPolicy::DEFAULT)
225
+ bytes = Exp.pack(nil, SET_INT, bit_offset, bit_size, value, policy.flags)
226
+ self.add_write(bin, bytes)
227
+ end
228
+
229
+ # Create expression that returns bits from byte[] bin starting at bit_offset for bit_size.
230
+ #
231
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
232
+ # bit_offset = 9
233
+ # bit_size = 5
234
+ # returns [0b10000000]
235
+ #
236
+ # ==== Examples
237
+ # # Bin "a" bits = [0b10000000]
238
+ # Exp.eq(
239
+ # BitExp.get(Exp.val(9), Exp.val(5), Exp.blobBin("a")),
240
+ # Exp.val(new byte[] {(byte)0b10000000}))
241
+ def self.get(bit_offset, bit_size, bin)
242
+ bytes = Exp.pack(nil, GET, bit_offset, bit_size)
243
+ self.add_read(bin, bytes, Exp::Type::BLOB)
244
+ end
245
+
246
+ # Create expression that returns integer count of set bits from byte[] bin starting at
247
+ # bit_offset for bit_size.
248
+ #
249
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
250
+ # bit_offset = 20
251
+ # bit_size = 4
252
+ # returns 2
253
+ #
254
+ # ==== Examples
255
+ # # Bin "a" bit count <= 2
256
+ # Exp.le(BitExp.count(Exp.val(0), Exp.val(5), Exp.blobBin("a")), Exp.val(2))
257
+ def self.count(bit_offset, bit_size, bin)
258
+ bytes = Exp.pack(nil, COUNT, bit_offset, bit_size)
259
+ self.add_read(bin, bytes, Exp::Type::INT)
260
+ end
261
+
262
+ # Create expression that returns integer bit offset of the first specified value bit in byte[] bin
263
+ # starting at bit_offset for bit_size.
264
+ #
265
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
266
+ # bit_offset = 24
267
+ # bit_size = 8
268
+ # value = true
269
+ # returns 5
270
+ #
271
+ # ==== Examples
272
+ # # lscan(a) == 5
273
+ # Exp.eq(BitExp.lscan(Exp.val(24), Exp.val(8), Exp.val(true), Exp.blobBin("a")), Exp.val(5))
274
+ #
275
+ # @param bit_offset offset int expression
276
+ # @param bit_size size int expression
277
+ # @param value boolean expression
278
+ # @param bin bin or blob value expression
279
+ def self.lscan(bit_offset, bit_size, value, bin)
280
+ bytes = Exp.pack(nil, LSCAN, bit_offset, bit_size, value)
281
+ self.add_read(bin, bytes, Exp::Type::INT)
282
+ end
283
+
284
+ # Create expression that returns integer bit offset of the last specified value bit in byte[] bin
285
+ # starting at bit_offset for bit_size.
286
+ # Example:
287
+ #
288
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
289
+ # bit_offset = 32
290
+ # bit_size = 8
291
+ # value = true
292
+ # returns 7
293
+ #
294
+ # ==== Examples
295
+ # # rscan(a) == 7
296
+ # Exp.eq(BitExp.rscan(Exp.val(32), Exp.val(8), Exp.val(true), Exp.blobBin("a")), Exp.val(7))
297
+ #
298
+ # @param bit_offset offset int expression
299
+ # @param bit_size size int expression
300
+ # @param value boolean expression
301
+ # @param bin bin or blob value expression
302
+ def self.rscan(bit_offset, bit_size, value, bin)
303
+ bytes = Exp.pack(nil, RSCAN, bit_offset, bit_size, value)
304
+ self.add_read(bin, bytes, Exp::Type::INT)
305
+ end
306
+
307
+ # Create expression that returns integer from byte[] bin starting at bit_offset for bit_size.
308
+ # Signed indicates if bits should be treated as a signed number.
309
+ #
310
+ # bin = [0b00000001, 0b01000010, 0b00000011, 0b00000100, 0b00000101]
311
+ # bit_offset = 8
312
+ # bit_size = 16
313
+ # signed = false
314
+ # returns 16899
315
+ #
316
+ # ==== Examples
317
+ # # getInt(a) == 16899
318
+ # Exp.eq(BitExp.getInt(Exp.val(8), Exp.val(16), false, Exp.blobBin("a")), Exp.val(16899))
319
+ def self.get_int(bit_offset, bit_size, signed, bin)
320
+ bytes = self.pack_get_int(bit_offset, bit_size, signed)
321
+ self.add_read(bin, bytes, Exp::Type::INT)
322
+ end
323
+
324
+ private
325
+
326
+ MODULE = 1
327
+ RESIZE = 0
328
+ INSERT = 1
329
+ REMOVE = 2
330
+ SET = 3
331
+ OR = 4
332
+ XOR = 5
333
+ AND = 6
334
+ NOT = 7
335
+ LSHIFT = 8
336
+ RSHIFT = 9
337
+ ADD = 10
338
+ SUBTRACT = 11
339
+ SET_INT = 12
340
+ GET = 50
341
+ COUNT = 51
342
+ LSCAN = 52
343
+ RSCAN = 53
344
+ GET_INT = 54
345
+
346
+ INT_FLAGS_SIGNED = 1
347
+
348
+ def self.pack_math(command, policy, bit_offset, bit_size, value, signed, bit_overflow_action)
349
+ Packer.use do |packer|
350
+ # Pack.init only required when CTX is used and server does not support CTX for bit operations.
351
+ # Pack.init(packer, ctx)
352
+ packer.write_array_header(6)
353
+ packer.write(command)
354
+ bit_offset.pack(packer)
355
+ bit_size.pack(packer)
356
+ value.pack(packer)
357
+ packer.write(policy.flags)
358
+
359
+ flags = bit_overflow_action
360
+ flags |= INT_FLAGS_SIGNED if signed
361
+
362
+ packer.write(flags)
363
+ return packer.bytes
364
+ end
365
+ end
366
+
367
+ def self.pack_get_int(bit_offset, bit_size, signed)
368
+ Packer.use do |packer|
369
+ # Pack.init only required when CTX is used and server does not support CTX for bit operations.
370
+ # Pack.init(packer, ctx)
371
+ packer.write_array_header(signed ? 4 : 3)
372
+ packer.write(GET_INT)
373
+ bit_offset.pack(packer)
374
+ bit_size.pack(packer)
375
+ packer.write(INT_FLAGS_SIGNED) if signed
376
+ return packer.bytes
377
+ end
378
+ end
379
+
380
+ def self.add_write(bin, bytes)
381
+ Exp::Module.new(bin, bytes, Exp::Type::BLOB, MODULE | Exp::MODIFY)
382
+ end
383
+
384
+ def self.add_read(bin, bytes, ret_type)
385
+ Exp::Module.new(bin, bytes, ret_type, MODULE)
386
+ end
387
+ end # class
388
+ end # module
@@ -0,0 +1,169 @@
1
+ # encoding: utf-8
2
+ # Copyright 2014-2022 Aerospike, Inc.
3
+ #
4
+ # Portions may be licensed to Aerospike, Inc. under one or more contributor
5
+ # license agreements.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License") you may no
8
+ # use this file except in compliance with the License. You may obtain a copy of
9
+ # the License at http:#www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13
+ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14
+ # License for the specific language governing permissions and limitations under
15
+ # the License.
16
+
17
+ module Aerospike
18
+ # HyperLogLog (HLL) expression generator. See {@link Exp}.
19
+ #
20
+ # The bin expression argument in these methods can be a reference to a bin or the
21
+ # result of another expression. Expressions that modify bin values are only used
22
+ # for temporary expression evaluation and are not permanently applied to the bin.
23
+ # HLL modify expressions return the HLL bin's value.
24
+ class Exp::HLL
25
+
26
+ # Create expression that creates a new HLL or resets an existing HLL with minhash bits.
27
+ #
28
+ # @param policy write policy, use {@link HLLPolicy#Default} for default
29
+ # @param index_bit_count number of index bits. Must be between 4 and 16 inclusive.
30
+ # @param min_hash_bit_count number of min hash bits. Must be between 4 and 51 inclusive.
31
+ # Also, index_bit_count + min_hash_bit_count must be <= 64. Optional.
32
+ # @param bin HLL bin or value expression
33
+ def self.init(index_bit_count, bin, min_hash_bit_count: Exp.int_val(-1), policy: CDT::HLLPolicy::DEFAULT)
34
+ bytes = Exp.pack(nil, INIT, index_bit_count, min_hash_bit_count, policy.flags)
35
+ self.add_write(bin, bytes)
36
+ end
37
+
38
+ # Create expression that adds values to a HLL set and returns HLL set. If HLL bin does not
39
+ # exist, use index_bit_count and min_hash_bit_count to create HLL set.
40
+ #
41
+ # ==== Examples
42
+ # # Add values to HLL bin "a" and check count > 7
43
+ # Exp.gt(
44
+ # HLLExp.getCount(
45
+ # HLLExp.add(HLLPolicy.Default, Exp.val(list), Exp.val(10), Exp.val(20), Exp.hllBin("a"))),
46
+ # Exp.val(7))
47
+ #
48
+ # @param policy write policy, use {@link HLLPolicy#Default} for default
49
+ # @param list list bin or value expression of values to be added
50
+ # @param index_bit_count number of index bits expression. Must be between 4 and 16 inclusive.
51
+ # @param min_hash_bit_count number of min hash bits expression. Must be between 4 and 51 inclusive.
52
+ # Also, index_bit_count + min_hash_bit_count must be <= 64.
53
+ # @param bin HLL bin or value expression
54
+ def self.add(list, bin, policy: CDT::HLLPolicy::DEFAULT, index_bit_count: Exp.val(-1), min_hash_bit_count: Exp.val(-1))
55
+ bytes = Exp.pack(nil, ADD, list, index_bit_count, min_hash_bit_count, policy.flags)
56
+ self.add_write(bin, bytes)
57
+ end
58
+
59
+ # Create expression that returns estimated number of elements in the HLL bin.
60
+ #
61
+ # ==== Examples
62
+ # # HLL bin "a" count > 7
63
+ # Exp.gt(HLLExp.getCount(Exp.hllBin("a")), Exp.val(7))
64
+ def self.get_count(bin)
65
+ bytes = Exp.pack(nil, COUNT)
66
+ self.add_read(bin, bytes, Exp::Type::INT)
67
+ end
68
+
69
+ # Create expression that returns a HLL object that is the union of all specified HLL objects
70
+ # in the list with the HLL bin.
71
+ #
72
+ # ==== Examples
73
+ # # Union of HLL bins "a" and "b"
74
+ # HLLExp.getUnion(Exp.hllBin("a"), Exp.hllBin("b"))
75
+ #
76
+ # # Union of local HLL list with bin "b"
77
+ # HLLExp.getUnion(Exp.val(list), Exp.hllBin("b"))
78
+ def self.get_union(list, bin)
79
+ bytes = Exp.pack(nil, UNION, list)
80
+ self.add_read(bin, bytes, Exp::Type::HLL)
81
+ end
82
+
83
+ # Create expression that returns estimated number of elements that would be contained by
84
+ # the union of these HLL objects.
85
+ #
86
+ # ==== Examples
87
+ # # Union count of HLL bins "a" and "b"
88
+ # HLLExp.getUnionCount(Exp.hllBin("a"), Exp.hllBin("b"))
89
+ #
90
+ # # Union count of local HLL list with bin "b"
91
+ # HLLExp.getUnionCount(Exp.val(list), Exp.hllBin("b"))
92
+ def self.get_union_count(list, bin)
93
+ bytes = Exp.pack(nil, UNION_COUNT, list)
94
+ self.add_read(bin, bytes, Exp::Type::INT)
95
+ end
96
+
97
+ # Create expression that returns estimated number of elements that would be contained by
98
+ # the intersection of these HLL objects.
99
+ #
100
+ # ==== Examples
101
+ # # Intersect count of HLL bins "a" and "b"
102
+ # HLLExp.getIntersectCount(Exp.hllBin("a"), Exp.hllBin("b"))
103
+ #
104
+ # # Intersect count of local HLL list with bin "b"
105
+ # HLLExp.getIntersectCount(Exp.val(list), Exp.hllBin("b"))
106
+ def self.get_intersect_count(list, bin)
107
+ bytes = Exp.pack(nil, INTERSECT_COUNT, list)
108
+ self.add_read(bin, bytes, Exp::Type::INT)
109
+ end
110
+
111
+ # Create expression that returns estimated similarity of these HLL objects as a
112
+ # 64 bit float.
113
+ #
114
+ # ==== Examples
115
+ # # Similarity of HLL bins "a" and "b" >= 0.75
116
+ # Exp.ge(HLLExp.getSimilarity(Exp.hllBin("a"), Exp.hllBin("b")), Exp.val(0.75))
117
+ def self.get_similarity(list, bin)
118
+ bytes = Exp.pack(nil, SIMILARITY, list)
119
+ self.add_read(bin, bytes, Exp::Type::FLOAT)
120
+ end
121
+
122
+ # Create expression that returns index_bit_count and min_hash_bit_count used to create HLL bin
123
+ # in a list of longs. list[0] is index_bit_count and list[1] is min_hash_bit_count.
124
+ #
125
+ # ==== Examples
126
+ # # Bin "a" index_bit_count < 10
127
+ # Exp.lt(
128
+ # ListExp.getByIndex(ListReturnType.VALUE, Exp::Type::INT, Exp.val(0),
129
+ # HLLExp.describe(Exp.hllBin("a"))),
130
+ # Exp.val(10))
131
+ def self.describe(bin)
132
+ bytes = Exp.pack(nil, DESCRIBE)
133
+ self.add_read(bin, bytes, Exp::Type::LIST)
134
+ end
135
+
136
+ # Create expression that returns one if HLL bin may contain all items in the list.
137
+ #
138
+ # ==== Examples
139
+ # # Bin "a" may contain value "x"
140
+ # ArrayList<Value> list = new ArrayList<Value>()
141
+ # list.add(Value.get("x"))
142
+ # Exp.eq(HLLExp.mayContain(Exp.val(list), Exp.hllBin("a")), Exp.val(1))
143
+ def self.may_contain(list, bin)
144
+ bytes = Exp.pack(nil, MAY_CONTAIN, list)
145
+ self.add_read(bin, bytes, Exp::Type::INT)
146
+ end
147
+
148
+ private
149
+
150
+ MODULE = 2
151
+ INIT = 0
152
+ ADD = 1
153
+ COUNT = 50
154
+ UNION = 51
155
+ UNION_COUNT = 52
156
+ INTERSECT_COUNT = 53
157
+ SIMILARITY = 54
158
+ DESCRIBE = 55
159
+ MAY_CONTAIN = 56
160
+
161
+ def self.add_write(bin, bytes)
162
+ Exp::Module.new(bin, bytes, Exp::Type::HLL, MODULE | Exp::MODIFY)
163
+ end
164
+
165
+ def self.add_read(bin, bytes, ret_type)
166
+ Exp::Module.new(bin, bytes, ret_type, MODULE)
167
+ end
168
+ end
169
+ end