hbase-jruby 0.1.1-java → 0.1.2-java

Sign up to get free protection for your applications and to get access to all the features.
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
+