hbase-jruby 0.1.1-java → 0.1.2-java

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.
data/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ Changelog
2
+ =========
3
+
4
+ 0.1.2
5
+ -----
6
+
7
+ - Dropped Bignum support. Automatic conversion from Fixnum to Bignum (or vice versa)
8
+ will produce columns whose values are of heterogeneous types, that are impossible to be read in a consistent way.
9
+ You can use BigDecimal type instead for large numbers.
10
+ - Added `HBase::Scoped#while` which allows early termination of scan
11
+ with [WhileMatchFilter](http://hbase.apache.org/apidocs/org/apache/hadoop/hbase/filter/WhileMatchFilter.html)
12
+ - Filtering with regular expressions
13
+ - Implemented comparator for `HBase::Result`
14
+ - Added coprocessor administration methods
15
+ - Basic aggregation with Coprocessor
16
+ - `HBase::Scoped#count` with block
17
+ - Allows PUT operation with timestamps
data/README.md CHANGED
@@ -9,7 +9,7 @@ Anyhow, JRuby is Ruby, not Java, right?
9
9
 
10
10
  *hbase-jruby* provides the followings:
11
11
  - Easy, Ruby-esque interface for the fundamental HBase operations
12
- - ActiveRecord-like method chaining for scanning tables
12
+ - ActiveRecord-like method chaining for data retrieval
13
13
  - Automatic Hadoop/HBase dependency resolution
14
14
 
15
15
  ## A quick example
@@ -17,6 +17,8 @@ Anyhow, JRuby is Ruby, not Java, right?
17
17
  ```ruby
18
18
  require 'hbase-jruby'
19
19
 
20
+ HBase.resolve_dependency! 'cdh4.1.2'
21
+
20
22
  hbase = HBase.new
21
23
  table = hbase.table(:test_table)
22
24
 
@@ -25,16 +27,17 @@ table.put :rowkey1 => { 'cf1:a' => 100, 'cf2:b' => "Hello" }
25
27
 
26
28
  # GET
27
29
  row = table.get(:rowkey1)
28
- number = row.integer('cf1:a')
30
+ number = row.fixnum('cf1:a')
29
31
  string = row.string('cf1:b')
30
32
 
31
33
  # SCAN
32
34
  table.range('rowkey1'..'rowkey9').
33
35
  filter('cf1:a' => 100..200, # cf1:a between 100 and 200
34
- 'cf2:b' => 'Hello', # cf1:b = 'Hello'
35
- 'cf2:c' => ['foo', 'bar']). # cf2:c in ('foo', 'bar')
36
+ 'cf1:b' => 'Hello', # cf1:b = 'Hello'
37
+ 'cf2:c' => /world/i). # cf2:c matches /world/i
38
+ 'cf2:d' => ['foo', /^BAR/i], # cf2:d = 'foo' OR matches /^BAR/i
36
39
  project('cf1:a', 'cf2').each do |row|
37
- puts row.integer('cf1:a')
40
+ puts row.fixnum('cf1:a')
38
41
  end
39
42
 
40
43
  # DELETE
@@ -174,6 +177,14 @@ table.put 'rowkey1', 'cf1:col1' => "Hello", 'cf2:col2' => "World"
174
177
  table.put 'rowkey1' => { 'cf1:col1' => "Hello", 'cf2:col2' => "World" },
175
178
  'rowkey2' => { 'cf1:col1' => "Howdy", 'cf2:col2' => "World" },
176
179
  'rowkey3' => { 'cf1:col1' => "So long", 'cf2:col2' => "World" }
180
+
181
+ # Putting values with timestamps
182
+ table.put 'rowkey1' => {
183
+ 'cf1:col1' => {
184
+ 1353143856665 => "Hello",
185
+ 1352978648642 => "Goodbye" },
186
+ 'cf2:col2' => "World"
187
+ }
177
188
  ```
178
189
 
179
190
  ### GET
@@ -191,12 +202,12 @@ rowk = row.rowkey
191
202
  col0 = row.raw 'cf1:col0'
192
203
 
193
204
  # Decode column values
194
- col1 = row.string 'cf1:col1'
195
- col2 = row.fixnum 'cf1:col2'
196
- col3 = row.bignum 'cf1:col3'
197
- col4 = row.float 'cf1:col4'
198
- col5 = row.boolean 'cf1:col5'
199
- col6 = row.symbol 'cf1:col6'
205
+ col1 = row.string 'cf1:col1'
206
+ col2 = row.fixnum 'cf1:col2'
207
+ col3 = row.bigdecimal 'cf1:col3'
208
+ col4 = row.float 'cf1:col4'
209
+ col5 = row.boolean 'cf1:col5'
210
+ col6 = row.symbol 'cf1:col6'
200
211
 
201
212
  # Decode multiple columns at once
202
213
  row.string ['cf1:str1', 'cf1:str2']
@@ -225,13 +236,13 @@ row.strings ['cf1:str1', 'cf1:str2']
225
236
  # ]
226
237
 
227
238
  # Plural-form methods are provided for any other data types as well
228
- cols0 = row.raws 'cf1:col0'
229
- cols1 = row.strings 'cf1:col1'
230
- cols2 = row.fixnums 'cf1:col2'
231
- cols3 = row.bignums 'cf1:col3'
232
- cols4 = row.floats 'cf1:col4'
233
- cols5 = row.booleans 'cf1:col5'
234
- cols6 = row.symbols 'cf1:col6'
239
+ cols0 = row.raws 'cf1:col0'
240
+ cols1 = row.strings 'cf1:col1'
241
+ cols2 = row.fixnums 'cf1:col2'
242
+ cols3 = row.bigdecimals 'cf1:col3'
243
+ cols4 = row.floats 'cf1:col4'
244
+ cols5 = row.booleans 'cf1:col5'
245
+ cols6 = row.symbols 'cf1:col6'
235
246
  ```
236
247
 
237
248
  #### Intra-row scan
@@ -262,7 +273,7 @@ end
262
273
  schema = {
263
274
  'cf1:col1' => :string,
264
275
  'cf1:col2' => :fixnum,
265
- 'cf1:col3' => :bignum,
276
+ 'cf1:col3' => :bigdecimal,
266
277
  'cf1:col4' => :float,
267
278
  'cf1:col5' => :boolean,
268
279
  'cf1:col6' => :symbol }
@@ -359,6 +370,7 @@ table.range('A'..'Z'). # Row key range,
359
370
  filter('cf2:d' => 100..200). # Range filter on cf2:d
360
371
  filter('cf2:e' => [10, 20..30]). # Set-inclusion condition on cf2:e
361
372
  filter(RandomRowFilter.new(0.5)). # Any Java HBase filter
373
+ while('cf2:f' => { ne: 'OPEN' }). # Early termination of scan
362
374
  limit(10). # Limits the size of the result set
363
375
  versions(2). # Only fetches 2 versions for each value
364
376
  batch(100). # Batch size for scan set to 100
@@ -366,7 +378,7 @@ table.range('A'..'Z'). # Row key range,
366
378
  to_a # To Array
367
379
  ```
368
380
 
369
- ### range
381
+ ### *range*
370
382
 
371
383
  `HBase::Scoped#range` method is used to filter rows based on their row keys.
372
384
 
@@ -416,7 +428,7 @@ scope.range(1, 100).
416
428
  # Same as `scope.range(1, 1000)`
417
429
  ```
418
430
 
419
- ### filter
431
+ ### *filter*
420
432
 
421
433
  You can configure server-side filtering of rows and columns with `HBase::Scoped#filter` calls.
422
434
  Multiple calls have conjunctive effects.
@@ -424,22 +436,56 @@ Multiple calls have conjunctive effects.
424
436
  ```ruby
425
437
  # Range scanning the table with filters
426
438
  table.range(nil, 1000).
427
- filter('cf1:a' => 'Hello', # cf1:a = 'Hello'
428
- 'cf1:b' => 100...200, # cf1:b between 100 and 200
429
- 'cf1:c' => %w[A B C], # cf1:c in ('A', 'B', 'C')
430
- 'cf1:d' => ['A'...'B', 'C'], # ('A' <= cf1:d < 'B') or cf1:d = 'C'
431
- 'cf1:e' => { gt: 1000, lte: 2000 }). # cf1:e > 1000 and cf1:e <= 2000
432
- 'cf1:f' => { ne: 1000 }). # cf1:f != 1000
433
- # Supported operators: gt, lt, gte, lte, eq, ne
434
- filter('cf1:g' => ['Alice'..'Bob', 'Cat']). # Multiple calls for conjunctive filtering
439
+ filter(
440
+ # Numbers and characters: Checks if the value is equal to the given value
441
+ 'cf1:a' => 'Hello',
442
+ 'cf1:b' => 1024,
443
+
444
+ # Range of numbers or characters: Checks if the value falls within the range
445
+ 'cf1:c' => 100..200,
446
+ 'cf1:d' => 'A'..'C',
447
+
448
+ # Regular expression: Checks if the value matches the regular expression
449
+ 'cf1:e' => /world$/i,
450
+
451
+ # Hash: Tests the value with 6 types of operators (:gt, :lt, :gte, :lte, :eq, :ne)
452
+ 'cf1:f' => { gt: 1000, lte: 2000 },
453
+ 'cf1:g' => { ne: 1000 },
454
+
455
+ # Array of the aforementioned types: OR condition (disjunctive)
456
+ 'cf1:h' => %w[A B C],
457
+ 'cf1:i' => ['A'...'B', 'C', /^D/, { lt: 'F' }]).
458
+
459
+ # Multiple calls for conjunctive filtering
460
+ filter('cf1:j' => ['Alice'..'Bob', 'Cat']).
461
+
462
+ # Any number of Java filters can be applied
435
463
  filter(org.apache.hadoop.hbase.filter.RandomRowFilter.new(0.5)).
436
- # Any number of Java filters can be applied
437
- each do |record|
464
+ each do |record|
438
465
  # ...
439
466
  end
440
467
  ```
441
468
 
442
- ### project
469
+ ### *while*
470
+
471
+ `HBase::Scoped#while` method takes the same parameters as `filter` method, the difference is that
472
+ each filtering condition passed to `while` method is wrapped by `WhileMatchFilter`,
473
+ which aborts scan immediately when the condition is not met at a certain row.
474
+ See the following example.
475
+
476
+ ```ruby
477
+ (0...30).each do |idx|
478
+ table.put idx, 'cf1:a' => idx % 10
479
+ end
480
+
481
+ table.filter('cf1:a' => { lte: 1 }).to_a
482
+ # 0, 1, 10, 11, 20, 21
483
+ table.while('cf1:a' => { lte: 1 }).to_a
484
+ # 0, 1
485
+ # Scan terminates immediately when condition not met.
486
+ ```
487
+
488
+ ### *project*
443
489
 
444
490
  `HBase::Scoped#project` allows you to fetch only a subset of columns from each row.
445
491
  Multiple calls have additive effects.
@@ -521,6 +567,44 @@ end
521
567
  scoped.count
522
568
  ```
523
569
 
570
+ ## Basic aggregation using coprocessor
571
+
572
+ *hbase-jruby* provides a few basic aggregation methods using
573
+ the built-in coprocessor called
574
+ `org.apache.hadoop.hbase.coprocessor.AggregateImplementation`.
575
+
576
+ To enable this feature, call `enable_aggregation!` method,
577
+ which will first disable the table, add the coprocessor, then enable it.
578
+
579
+ ```ruby
580
+ table.enable_aggregation!
581
+ # Just a shorthand notation for
582
+ # table.add_coprocessor! 'org.apache.hadoop.hbase.coprocessor.AggregateImplementation'
583
+ ```
584
+
585
+ Then you can get the sum, average, minimum, maximum, row count, and standard deviation
586
+ of the projected columns.
587
+
588
+ ```ruby
589
+ # cf1:a must hold 8-byte integer values
590
+ table.project('cf1:a').aggregate(:sum)
591
+ table.project('cf1:a').aggregate(:avg)
592
+ table.project('cf1:a').aggregate(:min)
593
+ table.project('cf1:a').aggregate(:max)
594
+ table.project('cf1:a').aggregate(:std)
595
+ table.project('cf1:a').aggregate(:row_count)
596
+
597
+ # Aggregation of multiple columns
598
+ table.project('cf1:a', 'cf1:b').aggregate(:sum)
599
+ ```
600
+
601
+ By default, aggregate method assumes the column values are 8-byte integers.
602
+ For types other than that, you can pass your own ColumnInterpreter.
603
+
604
+ ```ruby
605
+ table.project('cf1:b').aggregate(:sum, MyColumnInterpreter.new)
606
+ ```
607
+
524
608
  ## Advanced topics
525
609
 
526
610
  ### Lexicographic scan order
@@ -556,7 +640,6 @@ table.get('rowkey').string(HBase::ColumnKey(:cf1, 100))
556
640
  # ...
557
641
  ```
558
642
 
559
-
560
643
  ### Table administration
561
644
 
562
645
  `HBase#Table` provides a few *synchronous* table administration methods.
@@ -588,6 +671,16 @@ table.alter_family! :cf2, :bloomfilter => :rowcol
588
671
 
589
672
  # Remove column family
590
673
  table.delete_family! :cf1
674
+
675
+ # Add Coprocessor
676
+ unless table.has_coprocessor?(cp_class_name1)
677
+ table.add_coprocessor! cp_class_name1
678
+ end
679
+ table.add_coprocessor! cp_class_name2,
680
+ :path => path, :priority => priority, :params => params
681
+
682
+ # Remove coprocessor
683
+ table.remove_coprocessor! cp_class_name1
591
684
  ```
592
685
 
593
686
  You can perform other types of administrative tasks
data/hbase-jruby.gemspec CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |gem|
12
12
  gem.summary = %q{Ruby-esque interface for accessing HBase from JRuby}
13
13
  gem.homepage = "https://github.com/junegunn/hbase-jruby"
14
14
  gem.platform = 'java'
15
+ gem.license = 'MIT'
15
16
 
16
17
  gem.files = `git ls-files`.split($/)
17
18
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,6 +1,7 @@
1
1
  require 'thread'
2
2
 
3
3
  class HBase
4
+ # @private
4
5
  module Admin
5
6
  private
6
7
  def with_admin
@@ -14,7 +14,7 @@ class Cell
14
14
 
15
15
  # Returns the rowkey of the cell decoded as the given type
16
16
  # @param [Symbol] type The type of the rowkey.
17
- # Can be one of :string, :symbol, :fixnum, :float, :bignum, :bigdecimal, :boolean and :raw.
17
+ # Can be one of :string, :symbol, :fixnum, :float, :bigdecimal, :boolean and :raw.
18
18
  # @return [String, byte[]]
19
19
  def rowkey type = :string
20
20
  Util.from_bytes type, @java.getRow
@@ -35,7 +35,7 @@ class Cell
35
35
 
36
36
  # Returns the column qualifier of the cell
37
37
  # @param [Symbol] type The type of the qualifier.
38
- # Can be one of :string, :symbol, :fixnum, :float, :bignum, :bigdecimal, :boolean and :raw.
38
+ # Can be one of :string, :symbol, :fixnum, :float, :bigdecimal, :boolean and :raw.
39
39
  # @return [Object]
40
40
  def qualifier type = :string
41
41
  Util.from_bytes type, @java.getQualifier
@@ -49,7 +49,7 @@ class Cell
49
49
  end
50
50
  alias ts timestamp
51
51
 
52
- # Returns the value of the cell as a Java byte array
52
+ # Returns the value of the cell as a Java byte array
53
53
  # @return [byte[]]
54
54
  def value
55
55
  @java.getValue
@@ -78,14 +78,6 @@ class Cell
78
78
  alias integer fixnum
79
79
  alias int fixnum
80
80
 
81
- # Returns the column value as a Bignum
82
- # @return [Bignum]
83
- def bignum
84
- Util.from_bytes :bignum, value
85
- end
86
- alias biginteger bignum
87
- alias bigint bignum
88
-
89
81
  # Returns the column value as a BigDecimal
90
82
  # @return [BigDecimal]
91
83
  def bigdecimal
@@ -1,14 +1,14 @@
1
1
  require 'bigdecimal'
2
2
 
3
- # Represents a row returned by HBase
4
3
  class HBase
4
+ # Represents a row returned by HBase
5
5
  # @author Junegunn Choi <junegunn.c@gmail.com>
6
6
  class Result
7
7
  include Enumerable
8
-
8
+
9
9
  # Returns the rowkey of the row
10
10
  # @param [Symbol] type The type of the rowkey
11
- # Can be one of :string, :symbol, :fixnum, :float, :bignum, :bigdecimal, :boolean and :raw.
11
+ # Can be one of :string, :symbol, :fixnum, :float, :bigdecimal, :boolean and :raw.
12
12
  # @return [String, byte[]]
13
13
  def rowkey type = :string
14
14
  Util.from_bytes type, @result.getRow
@@ -55,7 +55,7 @@ class Result
55
55
  name = ColumnKey.new(cf, cq)
56
56
  type = schema[name]
57
57
 
58
- ret[name] =
58
+ ret[name] =
59
59
  Hash[
60
60
  tsmap.map { |ts, val|
61
61
  [ ts, type ? Util.from_bytes(type, val) : val ]
@@ -71,7 +71,7 @@ class Result
71
71
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
72
72
  # @return [byte[]] Byte array representation of the latest value
73
73
  # @overload raw(columns)
74
- # For each column specified,
74
+ # For each column specified,
75
75
  # returns the latest column value as a byte array
76
76
  # @param [<String|HBase::ColumnKey>] column "FAMILY:QUALIFIER" expression or ColumnKey object.
77
77
  # @return [Array<byte[]>] Byte array representations of the latest values
@@ -91,7 +91,7 @@ class Result
91
91
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
92
92
  # @return [Hash<Fixnum, byte[]>]
93
93
  # @overload raws(columns)
94
- # For each column specified,
94
+ # For each column specified,
95
95
  # returns all versions of column values as byte arrays in a Hash indexed by their timestamps
96
96
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
97
97
  # @return [Array<Hash<Fixnum, byte[]>>]
@@ -111,7 +111,7 @@ class Result
111
111
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
112
112
  # @return [String]
113
113
  # @overload string(columns)
114
- # For each column specified,
114
+ # For each column specified,
115
115
  # returns the latest column value as a String
116
116
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
117
117
  # @return [Array<String>]
@@ -125,7 +125,7 @@ class Result
125
125
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
126
126
  # @return [Hash<Fixnum, String>]
127
127
  # @overload strings(columns)
128
- # For each column specified,
128
+ # For each column specified,
129
129
  # returns all versions of column values as Strings in a Hash indexed by their timestamps
130
130
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
131
131
  # @return [Array<Hash<Fixnum, String>>]
@@ -139,7 +139,7 @@ class Result
139
139
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
140
140
  # @return [Symbol]
141
141
  # @overload symbol(columns)
142
- # For each column specified,
142
+ # For each column specified,
143
143
  # returns the latest column values as a Symbol
144
144
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
145
145
  # @return [Array<Symbol>]
@@ -153,7 +153,7 @@ class Result
153
153
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
154
154
  # @return [Hash<Fixnum, Symbol>]
155
155
  # @overload symbols(columns)
156
- # For each column specified,
156
+ # For each column specified,
157
157
  # returns all versions of column values as Symbols in a Hash indexed by their timestamps
158
158
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
159
159
  # @return [Array<Hash<Fixnum, Symbol>>]
@@ -167,7 +167,7 @@ class Result
167
167
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
168
168
  # @return [Fixnum]
169
169
  # @overload fixnum(columns)
170
- # For each column specified,
170
+ # For each column specified,
171
171
  # returns the latest column values as a Fixnum
172
172
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
173
173
  # @return [Array<Fixnum>]
@@ -182,7 +182,7 @@ class Result
182
182
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
183
183
  # @return [Hash<Fixnum, Fixnum>]
184
184
  # @overload fixnums(columns)
185
- # For each column specified,
185
+ # For each column specified,
186
186
  # returns all versions of column values as Fixnums in a Hash indexed by their timestamps
187
187
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
188
188
  # @return [Array<Hash<Fixnum, Fixnum>>]
@@ -192,42 +192,12 @@ class Result
192
192
  alias integers fixnums
193
193
  alias ints fixnums
194
194
 
195
- # @overload bignum(column)
196
- # Returns the latest column value as a Bignum
197
- # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
198
- # @return [Bignum]
199
- # @overload bignum(columns)
200
- # For each column specified,
201
- # returns the latest column values as a Bignum
202
- # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
203
- # @return [Array<Bignum>]
204
- def bignum cols
205
- decode_values :bignum, cols
206
- end
207
- alias biginteger bignum
208
- alias bigint bignum
209
-
210
- # @overload bignums(column)
211
- # Returns all versions of column values as Bignums in a Hash indexed by their timestamps
212
- # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
213
- # @return [Hash<Fixnum, Bignum>]
214
- # @overload bignums(columns)
215
- # For each column specified,
216
- # returns all versions of column values as Bignums in a Hash indexed by their timestamps
217
- # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
218
- # @return [Array<Hash<Fixnum, Bignum>>]
219
- def bignums cols
220
- decode_values :bignum, cols, true
221
- end
222
- alias bigintegers bignums
223
- alias bigints bignums
224
-
225
195
  # @overload bigdecimal(column)
226
196
  # Returns the latest column value as a BigDecimal
227
197
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
228
198
  # @return [BigDecimal]
229
199
  # @overload bigdecimal(columns)
230
- # For each column specified,
200
+ # For each column specified,
231
201
  # returns the latest column values as a BigDecimal
232
202
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
233
203
  # @return [Array<BigDecimal>]
@@ -240,7 +210,7 @@ class Result
240
210
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
241
211
  # @return [Hash<Fixnum, BigDecimal>]
242
212
  # @overload bigdecimals(columns)
243
- # For each column specified,
213
+ # For each column specified,
244
214
  # returns all versions of column values as BigDecimals in a Hash indexed by their timestamps
245
215
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
246
216
  # @return [Array<Hash<Fixnum, BigDecimal>>]
@@ -253,7 +223,7 @@ class Result
253
223
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
254
224
  # @return [Float]
255
225
  # @overload float(columns)
256
- # For each column specified,
226
+ # For each column specified,
257
227
  # returns the latest column values as a Float
258
228
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
259
229
  # @return [Array<Float>]
@@ -267,7 +237,7 @@ class Result
267
237
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
268
238
  # @return [Hash<Fixnum, Float>]
269
239
  # @overload floats(columns)
270
- # For each column specified,
240
+ # For each column specified,
271
241
  # returns all versions of column values as Floats in a Hash indexed by their timestamps
272
242
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
273
243
  # @return [Array<Hash<Fixnum, Float>>]
@@ -281,7 +251,7 @@ class Result
281
251
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
282
252
  # @return [true, false]
283
253
  # @overload boolean(columns)
284
- # For each column specified,
254
+ # For each column specified,
285
255
  # returns the latest column values as a boolean value
286
256
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
287
257
  # @return [Array<true|false>]
@@ -295,7 +265,7 @@ class Result
295
265
  # @param [String, HBase::ColumnKey] column "FAMILY:QUALIFIER" expression or ColumnKey object.
296
266
  # @return [Hash<Fixnum, true|false>]
297
267
  # @overload booleans(columns)
298
- # For each column specified,
268
+ # For each column specified,
299
269
  # returns all versions of column values as boolean values in a Hash indexed by their timestamps
300
270
  # @param [Array<String|HBase::ColumnKey>] columns Array of "FAMILY:QUALIFIER" expressions and ColumnKey objects.
301
271
  # @return [Array<Hash<Fixnum, true|false>>]
@@ -304,6 +274,10 @@ class Result
304
274
  end
305
275
  alias bools booleans
306
276
 
277
+ def <=> other
278
+ Bytes.compareTo(rowkey(:raw), other.rowkey(:raw))
279
+ end
280
+
307
281
  private
308
282
  HASH_TEMPLATE = {}.tap { |h|
309
283
  h.instance_eval do
@@ -326,7 +300,9 @@ private
326
300
  cols.map { |col|
327
301
  cf, cq = Util.parse_column_name(col)
328
302
  if with_versions
329
- Hash[ allmap[cf][cq] ]
303
+ # Need to make it a Ruby hash:
304
+ # Prevents implicit conversion from ruby type to java type when updating the Hash
305
+ Hash[ allmap.fetch(cf, {}).fetch(cq, {}) ]
330
306
  else
331
307
  @result.getValue cf, cq
332
308
  end
@@ -365,7 +341,7 @@ private
365
341
  def parse_schema schema
366
342
  {}.tap { |ret|
367
343
  schema.each do |name, type|
368
- ck =
344
+ ck =
369
345
  case name
370
346
  when ColumnKey
371
347
  name
@@ -378,5 +354,5 @@ private
378
354
  }
379
355
  end
380
356
  end#Result
381
- end#HBase
357
+ end#HBase
382
358
 
@@ -0,0 +1,47 @@
1
+ class HBase
2
+ class Scoped
3
+ # Basic data aggregation with coprocessor based on AggregateImplementation
4
+ # @author Junegunn Choi <junegunn.c@gmail.com>
5
+ module Aggregation
6
+ module Admin
7
+ # Enables aggregation support for the table
8
+ # @return [nil]
9
+ def enable_aggregation!
10
+ add_coprocessor! 'org.apache.hadoop.hbase.coprocessor.AggregateImplementation'
11
+ end
12
+ end
13
+
14
+ # Performs aggregation with coprocessor
15
+ # @param [Symbol] op Aggregation type: :sum, :min, :max, :avg, :std, :row_count
16
+ # @param [Symbol, org.apache.hadoop.hbase.coprocessor.ColumnInterpreter] type
17
+ # Column type (only :fixnum is supported as of now) or ColumnInterpreter object used to decode the value
18
+ def aggregate op, type = :fixnum
19
+ aggregation_impl op, type
20
+ end
21
+
22
+ private
23
+ def aggregation_impl method, type
24
+ raise ArgumentError.new("No column specified") if method != :row_count && @project.empty?
25
+
26
+ @aggregation_client ||= AggregationClient.new(table.config)
27
+ @aggregation_client.send(
28
+ method,
29
+ Util.to_bytes(table.name),
30
+ column_interpreter_for(type),
31
+ filtered_scan)
32
+ end
33
+
34
+ def column_interpreter_for type
35
+ case type
36
+ when :fixnum, :int, :integer
37
+ LongColumnInterpreter.new
38
+ when org.apache.hadoop.hbase.coprocessor.ColumnInterpreter
39
+ type
40
+ else
41
+ raise ArgumentError, "Column interpreter for #{type} not implemented."
42
+ end
43
+ end
44
+ end#Aggregation
45
+ end#Scoped
46
+ end#HBase
47
+