hbase-jruby 0.1.6-java → 0.2.0-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 +14 -0
- data/README.md +227 -94
- data/lib/hbase-jruby/admin.rb +3 -1
- data/lib/hbase-jruby/dependency.rb +37 -12
- data/lib/hbase-jruby/hbase.rb +53 -10
- data/lib/hbase-jruby/pom/pom.xml +1 -1
- data/lib/hbase-jruby/scoped.rb +40 -2
- data/lib/hbase-jruby/table/admin.rb +442 -0
- data/lib/hbase-jruby/table/inspection.rb +109 -0
- data/lib/hbase-jruby/table.rb +29 -388
- data/lib/hbase-jruby/util.rb +16 -1
- data/lib/hbase-jruby/version.rb +1 -1
- data/lib/hbase-jruby.rb +2 -0
- data/test/helper.rb +4 -7
- data/test/test_cell.rb +2 -2
- data/test/test_hbase.rb +10 -3
- data/test/test_scoped.rb +35 -0
- data/test/test_table.rb +36 -26
- data/test/test_table_admin.rb +118 -31
- metadata +4 -2
data/lib/hbase-jruby/hbase.rb
CHANGED
@@ -8,6 +8,30 @@ class HBase
|
|
8
8
|
|
9
9
|
include Admin
|
10
10
|
|
11
|
+
# @overload HBase.log4j=(filename)
|
12
|
+
# Configure Log4j logging with the given file
|
13
|
+
# @param [String] filename Path to log4j.properties file
|
14
|
+
# @return [nil]
|
15
|
+
# @overload HBase.log4j=(hash)
|
16
|
+
# Configure Log4j logging with the given Hash
|
17
|
+
# @param [Hash] hash Log4j properties in Ruby Hash
|
18
|
+
# @return [nil]
|
19
|
+
# @overload HBase.log4j=(props)
|
20
|
+
# Configure Log4j logging with the given Properties
|
21
|
+
# @param [java.util.Properties] props Properties object
|
22
|
+
# @return [nil]
|
23
|
+
def self.log4j= arg
|
24
|
+
if arg.is_a?(Hash)
|
25
|
+
props = java.util.Properties.new
|
26
|
+
arg.each do |k, v|
|
27
|
+
props.setProperty k.to_s, v.to_s
|
28
|
+
end
|
29
|
+
arg = props
|
30
|
+
end
|
31
|
+
|
32
|
+
org.apache.log4j.PropertyConfigurator.configure arg
|
33
|
+
end
|
34
|
+
|
11
35
|
# Connects to HBase
|
12
36
|
# @param [Hash] config A key-value pairs to build HBaseConfiguration from
|
13
37
|
def initialize config = {}
|
@@ -30,12 +54,15 @@ class HBase
|
|
30
54
|
end
|
31
55
|
end
|
32
56
|
@htable_pool = HTablePool.new @config, java.lang.Integer::MAX_VALUE
|
57
|
+
@closed = false
|
33
58
|
end
|
34
59
|
|
35
60
|
# Returns an HBaseAdmin object for administration
|
36
|
-
# @yield [
|
61
|
+
# @yield [admin] An HBaseAdmin object
|
62
|
+
# @yieldparam [org.apache.hadoop.hbase.client.HBaseAdmin] admin
|
37
63
|
# @return [org.apache.hadoop.hbase.client.HBaseAdmin]
|
38
64
|
def admin
|
65
|
+
check_closed
|
39
66
|
if block_given?
|
40
67
|
with_admin { |admin| yield admin }
|
41
68
|
else
|
@@ -46,37 +73,53 @@ class HBase
|
|
46
73
|
# Closes HTablePool and connection
|
47
74
|
# @return [nil]
|
48
75
|
def close
|
49
|
-
@
|
50
|
-
|
76
|
+
unless @closed
|
77
|
+
@htable_pool.close
|
78
|
+
HConnectionManager.deleteConnection(@config, true)
|
79
|
+
@closed = true
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# Returns whether if the connection is closed
|
84
|
+
# @return [Boolean]
|
85
|
+
def closed?
|
86
|
+
@closed
|
51
87
|
end
|
52
88
|
|
53
89
|
# Returns the list of HBase::Table instances
|
54
90
|
# @return [Array<HBase::Table>]
|
55
91
|
def tables
|
92
|
+
check_closed
|
56
93
|
table_names.map { |tn| table(tn) }
|
57
94
|
end
|
58
95
|
|
59
96
|
# Returns the list of table names
|
60
97
|
# @return [Array<String>]
|
61
98
|
def table_names
|
99
|
+
check_closed
|
62
100
|
with_admin { |admin| admin.list_tables.map(&:name_as_string) }
|
63
101
|
end
|
102
|
+
alias list table_names
|
64
103
|
|
65
|
-
# Creates HBase::Table instance for the specified name
|
104
|
+
# Creates an HBase::Table instance for the specified name
|
66
105
|
# @param [#to_s] table_name The name of the table
|
67
106
|
# @return [HBase::Table]
|
68
107
|
def table table_name
|
69
|
-
|
108
|
+
check_closed
|
109
|
+
|
110
|
+
ht = HBase::Table.send :new, self, @config, @htable_pool, table_name
|
70
111
|
|
71
112
|
if block_given?
|
72
|
-
|
73
|
-
yield ht
|
74
|
-
ensure
|
75
|
-
ht.close
|
76
|
-
end
|
113
|
+
yield ht
|
77
114
|
else
|
78
115
|
ht
|
79
116
|
end
|
80
117
|
end
|
118
|
+
alias [] table
|
119
|
+
|
120
|
+
private
|
121
|
+
def check_closed
|
122
|
+
raise RuntimeError, "Connection already closed" if closed?
|
123
|
+
end
|
81
124
|
end
|
82
125
|
|
data/lib/hbase-jruby/pom/pom.xml
CHANGED
data/lib/hbase-jruby/scoped.rb
CHANGED
@@ -6,6 +6,7 @@ class HBase
|
|
6
6
|
class Scoped
|
7
7
|
include Enumerable
|
8
8
|
include Scoped::Aggregation
|
9
|
+
include HBase::Util
|
9
10
|
|
10
11
|
attr_reader :table
|
11
12
|
|
@@ -59,7 +60,8 @@ class Scoped
|
|
59
60
|
end
|
60
61
|
|
61
62
|
# Iterate through the scope.
|
62
|
-
# @yield [
|
63
|
+
# @yield [row] Yields each row in the scope
|
64
|
+
# @yieldparam [HBase::Result] row
|
63
65
|
def each
|
64
66
|
if block_given?
|
65
67
|
begin
|
@@ -158,6 +160,21 @@ class Scoped
|
|
158
160
|
spawn :@limit, rows
|
159
161
|
end
|
160
162
|
|
163
|
+
# Returns an HBase::Scoped object with the specified time range
|
164
|
+
# @param [Fixnum|Time] min Minimum timestamp (inclusive)
|
165
|
+
# @param [Fixnum|Time] max Maximum timestamp (exclusive)
|
166
|
+
# @return [HBase::Scoped] HBase::Scoped object with the specified time range
|
167
|
+
def time_range min, max
|
168
|
+
spawn :@trange, [min, max].map { |e| time_to_long e }
|
169
|
+
end
|
170
|
+
|
171
|
+
# Returns an HBase::Scoped object with the specified timestamp
|
172
|
+
# @param [Fixnum|Time] ts Timestamp
|
173
|
+
# @return [HBase::Scoped] HBase::Scoped object with the specified timestamp
|
174
|
+
def at ts
|
175
|
+
spawn :@trange, time_to_long(ts)
|
176
|
+
end
|
177
|
+
|
161
178
|
# Returns an HBase::Scoped object with the specified projection
|
162
179
|
# @param [Array<String>] columns Array of column expressions
|
163
180
|
# @return [HBase::Scoped] HBase::Scoped object with the specified projection
|
@@ -212,6 +229,7 @@ private
|
|
212
229
|
@batch = nil
|
213
230
|
@caching = nil
|
214
231
|
@limit = nil
|
232
|
+
@trange = nil
|
215
233
|
end
|
216
234
|
|
217
235
|
def spawn *args
|
@@ -339,6 +357,14 @@ private
|
|
339
357
|
filters += @filters
|
340
358
|
|
341
359
|
get.setFilter FilterList.new(filters) unless filters.empty?
|
360
|
+
|
361
|
+
# Timerange / Timestamp
|
362
|
+
case @trange
|
363
|
+
when Array
|
364
|
+
get.setTimeRange *@trange
|
365
|
+
when Time, Fixnum
|
366
|
+
get.setTimeStamp @trange
|
367
|
+
end
|
342
368
|
}
|
343
369
|
end
|
344
370
|
|
@@ -412,6 +438,7 @@ private
|
|
412
438
|
|
413
439
|
def filtered_scan
|
414
440
|
Scan.new.tap { |scan|
|
441
|
+
# Range
|
415
442
|
range = @range || range_for_prefix
|
416
443
|
case range
|
417
444
|
when Range
|
@@ -430,15 +457,17 @@ private
|
|
430
457
|
raise ArgumentError, "Invalid range"
|
431
458
|
end if range
|
432
459
|
|
460
|
+
# Caching
|
433
461
|
scan.caching = @caching if @caching
|
434
462
|
|
435
|
-
# Filters
|
463
|
+
# Filters (with projection)
|
436
464
|
prefix_filter = [*build_prefix_filter].compact
|
437
465
|
filters = prefix_filter + @filters
|
438
466
|
filters += process_projection!(scan)
|
439
467
|
|
440
468
|
scan.setFilter FilterList.new(filters) unless filters.empty?
|
441
469
|
|
470
|
+
# Limit
|
442
471
|
if @limit
|
443
472
|
# setMaxResultSize not implemented in 0.92
|
444
473
|
if scan.respond_to?(:setMaxResultSize)
|
@@ -448,12 +477,21 @@ private
|
|
448
477
|
end
|
449
478
|
end
|
450
479
|
|
480
|
+
# Versions
|
451
481
|
if @versions
|
452
482
|
scan.setMaxVersions @versions
|
453
483
|
else
|
454
484
|
scan.setMaxVersions
|
455
485
|
end
|
456
486
|
|
487
|
+
# Timerange / Timestamp
|
488
|
+
case @trange
|
489
|
+
when Array
|
490
|
+
scan.setTimeRange *@trange
|
491
|
+
when Time, Fixnum
|
492
|
+
scan.setTimeStamp @trange
|
493
|
+
end
|
494
|
+
|
457
495
|
# Batch
|
458
496
|
scan.setBatch @batch if @batch
|
459
497
|
}
|
@@ -0,0 +1,442 @@
|
|
1
|
+
class HBase
|
2
|
+
class Table
|
3
|
+
# Checks if the table of the name exists
|
4
|
+
# @return [true, false] Whether table exists
|
5
|
+
def exists?
|
6
|
+
with_admin { |admin| admin.tableExists @name }
|
7
|
+
end
|
8
|
+
|
9
|
+
# Checks if the table is enabled
|
10
|
+
# @return [true, false] Whether table is enabled
|
11
|
+
def enabled?
|
12
|
+
with_admin { |admin| admin.isTableEnabled(@name) }
|
13
|
+
end
|
14
|
+
|
15
|
+
# Checks if the table is disabled
|
16
|
+
# @return [true, false] Whether table is disabled
|
17
|
+
def disabled?
|
18
|
+
!enabled?
|
19
|
+
end
|
20
|
+
|
21
|
+
# Creates the table
|
22
|
+
# @overload create!(column_family_name, props = {})
|
23
|
+
# Create the table with one column family of the given name
|
24
|
+
# @param [#to_s] The name of the column family
|
25
|
+
# @param [Hash] props Table properties
|
26
|
+
# @return [nil]
|
27
|
+
# @overload create!(column_family_hash, props = {})
|
28
|
+
# Create the table with the specified column families
|
29
|
+
# @param [Hash] Column family properties
|
30
|
+
# @param [Hash] props Table properties
|
31
|
+
# @return [nil]
|
32
|
+
# @example
|
33
|
+
# table.create!(
|
34
|
+
# # Column family with default options
|
35
|
+
# :cf1 => {},
|
36
|
+
# # Another column family with custom properties
|
37
|
+
# :cf2 => {
|
38
|
+
# :blockcache => true,
|
39
|
+
# :blocksize => 128 * 1024,
|
40
|
+
# :bloomfilter => :row,
|
41
|
+
# :compression => :snappy,
|
42
|
+
# :in_memory => true,
|
43
|
+
# :keep_deleted_cells => true,
|
44
|
+
# :min_versions => 2,
|
45
|
+
# :replication_scope => 0,
|
46
|
+
# :ttl => 100,
|
47
|
+
# :versions => 5
|
48
|
+
# }
|
49
|
+
# )
|
50
|
+
# @overload create!(table_descriptor)
|
51
|
+
# Create the table with the given HTableDescriptor
|
52
|
+
# @param [org.apache.hadoop.hbase.HTableDescriptor] Table descriptor
|
53
|
+
# @return [nil]
|
54
|
+
def create! desc, props = {}
|
55
|
+
splits =
|
56
|
+
if props[:splits]
|
57
|
+
raise ArgumentError, ":splits property must be an Array" if !props[:splits].is_a?(Array)
|
58
|
+
props[:splits].map { |e| Util.to_bytes(e).to_a }.to_java(Java::byte[])
|
59
|
+
end
|
60
|
+
|
61
|
+
todo = nil
|
62
|
+
with_admin do |admin|
|
63
|
+
raise RuntimeError, 'Table already exists' if admin.tableExists(@name)
|
64
|
+
|
65
|
+
case desc
|
66
|
+
when HTableDescriptor
|
67
|
+
patch_table_descriptor! desc, props
|
68
|
+
admin.createTable *[desc, splits].compact
|
69
|
+
when Symbol, String
|
70
|
+
todo = lambda { create!({desc => {}}, props) }
|
71
|
+
when Hash
|
72
|
+
htd = HTableDescriptor.new(@name.to_java_bytes)
|
73
|
+
patch_table_descriptor! htd, props
|
74
|
+
desc.each do |name, opts|
|
75
|
+
htd.addFamily hcd(name, opts)
|
76
|
+
end
|
77
|
+
|
78
|
+
admin.createTable *[htd, splits].compact
|
79
|
+
else
|
80
|
+
raise ArgumentError, 'Invalid table description'
|
81
|
+
end
|
82
|
+
end
|
83
|
+
todo.call if todo # Avoids mutex relocking
|
84
|
+
end
|
85
|
+
|
86
|
+
# Alters the table (synchronous)
|
87
|
+
# @param [Hash] props Table properties
|
88
|
+
# @return [nil]
|
89
|
+
# @yield [progress, total]
|
90
|
+
# @yieldparam [Fixnum] progress Number of regions updated
|
91
|
+
# @yieldparam [Fixnum] total Total number of regions
|
92
|
+
# @example
|
93
|
+
# table.alter!(
|
94
|
+
# :max_filesize => 512 * 1024 ** 2,
|
95
|
+
# :memstore_flushsize => 64 * 1024 ** 2,
|
96
|
+
# :readonly => false,
|
97
|
+
# :deferred_log_flush => true
|
98
|
+
# )
|
99
|
+
def alter! props, &block
|
100
|
+
_alter props, true, &block
|
101
|
+
end
|
102
|
+
|
103
|
+
# Alters the table (asynchronous)
|
104
|
+
# @see HBase::Table#alter!
|
105
|
+
def alter props
|
106
|
+
_alter props, false
|
107
|
+
end
|
108
|
+
|
109
|
+
# Adds the column family (synchronous)
|
110
|
+
# @param [#to_s] name The name of the column family
|
111
|
+
# @param [Hash] opts Column family properties
|
112
|
+
# @return [nil]
|
113
|
+
# @yield [progress, total]
|
114
|
+
# @yieldparam [Fixnum] progress Number of regions updated
|
115
|
+
# @yieldparam [Fixnum] total Total number of regions
|
116
|
+
def add_family! name, opts, &block
|
117
|
+
_add_family name, opts, true, &block
|
118
|
+
end
|
119
|
+
|
120
|
+
# Adds the column family (asynchronous)
|
121
|
+
# @see HBase::Table#add_family!
|
122
|
+
def add_family name, opts
|
123
|
+
_add_family name, opts, false
|
124
|
+
end
|
125
|
+
|
126
|
+
# Alters the column family
|
127
|
+
# @param [#to_s] name The name of the column family
|
128
|
+
# @param [Hash] opts Column family properties
|
129
|
+
# @return [nil]
|
130
|
+
# @yield [progress, total]
|
131
|
+
# @yieldparam [Fixnum] progress Number of regions updated
|
132
|
+
# @yieldparam [Fixnum] total Total number of regions
|
133
|
+
def alter_family! name, opts, &block
|
134
|
+
_alter_family name, opts, true, &block
|
135
|
+
end
|
136
|
+
|
137
|
+
# Alters the column family (asynchronous)
|
138
|
+
# @see HBase::Table#alter_family!
|
139
|
+
def alter_family name, opts
|
140
|
+
_alter_family name, opts, false
|
141
|
+
end
|
142
|
+
|
143
|
+
# Removes the column family
|
144
|
+
# @param [#to_s] name The name of the column family
|
145
|
+
# @return [nil]
|
146
|
+
# @yield [progress, total]
|
147
|
+
# @yieldparam [Fixnum] progress Number of regions updated
|
148
|
+
# @yieldparam [Fixnum] total Total number of regions
|
149
|
+
def delete_family! name, &block
|
150
|
+
_delete_family name, true, &block
|
151
|
+
end
|
152
|
+
|
153
|
+
# Removes the column family (asynchronous)
|
154
|
+
# @see HBase::Table#delete_family!
|
155
|
+
def delete_family name
|
156
|
+
_delete_family name, false
|
157
|
+
end
|
158
|
+
|
159
|
+
# Adds the table coprocessor to the table
|
160
|
+
# @param [String] class_name Full class name of the coprocessor
|
161
|
+
# @param [Hash] props Coprocessor properties
|
162
|
+
# @option props [String] path The path of the JAR file
|
163
|
+
# @option props [Fixnum] priority Coprocessor priority
|
164
|
+
# @option props [Hash<#to_s, #to_s>] params Arbitrary key-value parameter pairs passed into the coprocessor
|
165
|
+
# @yield [progress, total]
|
166
|
+
# @yieldparam [Fixnum] progress Number of regions updated
|
167
|
+
# @yieldparam [Fixnum] total Total number of regions
|
168
|
+
def add_coprocessor! class_name, props = {}, &block
|
169
|
+
_add_coprocessor class_name, props, true, &block
|
170
|
+
end
|
171
|
+
|
172
|
+
# Adds the table coprocessor to the table (asynchronous)
|
173
|
+
def add_coprocessor class_name, props = {}
|
174
|
+
_add_coprocessor class_name, props, false
|
175
|
+
end
|
176
|
+
|
177
|
+
# Removes the coprocessor from the table.
|
178
|
+
# @param [String] class_name Full class name of the coprocessor
|
179
|
+
# @return [nil]
|
180
|
+
# @yield [progress, total]
|
181
|
+
# @yieldparam [Fixnum] progress Number of regions updated
|
182
|
+
# @yieldparam [Fixnum] total Total number of regions
|
183
|
+
def remove_coprocessor! class_name, &block
|
184
|
+
_remove_coprocessor class_name, true, &block
|
185
|
+
end
|
186
|
+
|
187
|
+
# Removes the coprocessor from the table (asynchronous)
|
188
|
+
# @see HBase::Table#remove_coprocessor!
|
189
|
+
def remove_coprocessor class_name
|
190
|
+
_remove_coprocessor class_name, false
|
191
|
+
end
|
192
|
+
|
193
|
+
# Return if the table has the coprocessor of the given class name
|
194
|
+
# @param [String] class_name Full class name of the coprocessor
|
195
|
+
# @return [true, false]
|
196
|
+
def has_coprocessor? class_name
|
197
|
+
descriptor.hasCoprocessor(class_name)
|
198
|
+
end
|
199
|
+
|
200
|
+
# Splits the table region on the given split point (asynchronous)
|
201
|
+
# @param [*Object] split_keys
|
202
|
+
# @return [nil]
|
203
|
+
def split! *split_keys
|
204
|
+
_split split_keys, false
|
205
|
+
end
|
206
|
+
|
207
|
+
# Enables the table
|
208
|
+
# @return [nil]
|
209
|
+
def enable!
|
210
|
+
with_admin do |admin|
|
211
|
+
admin.enableTable @name unless admin.isTableEnabled(@name)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
# Disables the table
|
216
|
+
# @return [nil]
|
217
|
+
def disable!
|
218
|
+
with_admin do |admin|
|
219
|
+
admin.disableTable @name if admin.isTableEnabled(@name)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# Truncates the table by dropping it and recreating it.
|
224
|
+
# @return [nil]
|
225
|
+
def truncate!
|
226
|
+
htd = htable.get_table_descriptor
|
227
|
+
drop!
|
228
|
+
create! htd
|
229
|
+
end
|
230
|
+
|
231
|
+
# Drops the table
|
232
|
+
# @return [nil]
|
233
|
+
def drop!
|
234
|
+
with_admin do |admin|
|
235
|
+
raise RuntimeError, 'Table does not exist' unless admin.tableExists @name
|
236
|
+
|
237
|
+
admin.disableTable @name if admin.isTableEnabled(@name)
|
238
|
+
admin.deleteTable @name
|
239
|
+
close
|
240
|
+
end
|
241
|
+
end
|
242
|
+
|
243
|
+
private
|
244
|
+
COLUMN_PROPERTIES = {
|
245
|
+
:blockcache => { :set => :setBlockCacheEnabled, :get => :isBlockCacheEnabled },
|
246
|
+
:blocksize => { :set => :setBlocksize, :get => :getBlocksize },
|
247
|
+
:bloomfilter => { :set => :setBloomFilterType, :get => :getBloomFilterType },
|
248
|
+
:cache_blooms_on_write => { :set => :setCacheBloomsOnWrite, :get => :shouldCacheBloomsOnWrite },
|
249
|
+
:cache_data_on_write => { :set => :setCacheDataOnWrite, :get => :shouldCacheDataOnWrite },
|
250
|
+
:cache_index_on_write => { :set => :setCacheIndexesOnWrite, :get => :shouldCacheIndexesOnWrite },
|
251
|
+
:compression => { :set => :setCompressionType, :get => :getCompressionType },
|
252
|
+
:compression_compact => { :set => :setCompactionCompressionType, :get => :getCompactionCompression },
|
253
|
+
:data_block_encoding => { :set => :setDataBlockEncoding, :get => :getDataBlockEncoding },
|
254
|
+
:encode_on_disk => { :set => :setEncodeOnDisk, :get => nil },
|
255
|
+
:evict_blocks_on_close => { :set => :setEvictBlocksOnClose, :get => :shouldEvictBlocksOnClose },
|
256
|
+
:in_memory => { :set => :setInMemory, :get => :isInMemory },
|
257
|
+
:keep_deleted_cells => { :set => :setKeepDeletedCells, :get => :getKeepDeletedCells },
|
258
|
+
:min_versions => { :set => :setMinVersions, :get => :getMinVersions },
|
259
|
+
:replication_scope => { :set => :setScope, :get => :getScope },
|
260
|
+
:ttl => { :set => :setTimeToLive, :get => :getTimeToLive },
|
261
|
+
:versions => { :set => :setMaxVersions, :get => :getMaxVersions },
|
262
|
+
}
|
263
|
+
|
264
|
+
TABLE_PROPERTIES = {
|
265
|
+
:max_filesize => { :get => :getMaxFileSize, :set => :setMaxFileSize },
|
266
|
+
:readonly => { :get => :isReadOnly, :set => :setReadOnly },
|
267
|
+
:memstore_flushsize => { :get => :getMemStoreFlushSize, :set => :setMemStoreFlushSize },
|
268
|
+
:deferred_log_flush => { :get => :isDeferredLogFlush, :set => :setDeferredLogFlush },
|
269
|
+
}
|
270
|
+
|
271
|
+
MAX_SPLIT_WAIT = 30
|
272
|
+
|
273
|
+
def while_disabled admin
|
274
|
+
begin
|
275
|
+
admin.disableTable @name if admin.isTableEnabled(@name)
|
276
|
+
yield
|
277
|
+
ensure
|
278
|
+
admin.enableTable @name
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
def hcd name, opts
|
283
|
+
HColumnDescriptor.new(name.to_s).tap do |hcd|
|
284
|
+
opts.each do |key, val|
|
285
|
+
method = COLUMN_PROPERTIES[key] && COLUMN_PROPERTIES[key][:set]
|
286
|
+
if method
|
287
|
+
hcd.send method,
|
288
|
+
({
|
289
|
+
:bloomfilter => proc { |v|
|
290
|
+
enum =
|
291
|
+
if defined?(org.apache.hadoop.hbase.regionserver.StoreFile::BloomType)
|
292
|
+
org.apache.hadoop.hbase.regionserver.StoreFile::BloomType
|
293
|
+
else
|
294
|
+
# 0.95 or later
|
295
|
+
org.apache.hadoop.hbase.regionserver.BloomType
|
296
|
+
end
|
297
|
+
const_shortcut enum, v, "Invalid bloom filter type"
|
298
|
+
},
|
299
|
+
:compression => proc { |v|
|
300
|
+
const_shortcut Compression::Algorithm, v, "Invalid compression algorithm"
|
301
|
+
},
|
302
|
+
:compression_compact => proc { |v|
|
303
|
+
const_shortcut Compression::Algorithm, v, "Invalid compression algorithm"
|
304
|
+
},
|
305
|
+
:data_block_encoding => proc { |v|
|
306
|
+
const_shortcut org.apache.hadoop.hbase.io.encoding.DataBlockEncoding, v, "Invalid data block encoding algorithm"
|
307
|
+
}
|
308
|
+
}[key] || proc { |a| a }).call(val)
|
309
|
+
elsif key.is_a?(String)
|
310
|
+
hcd.setValue key, val.to_s
|
311
|
+
else
|
312
|
+
raise ArgumentError, "Invalid property: #{key}"
|
313
|
+
end
|
314
|
+
end#opts
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
def const_shortcut base, v, message
|
319
|
+
# Match by constant value
|
320
|
+
# - const_get doesn't work with symbols in 1.8 compatibility mode
|
321
|
+
if base.constants.map { |c| base.const_get c }.any? { |cv| v == cv }
|
322
|
+
v
|
323
|
+
# Match by constant name (uppercase)
|
324
|
+
elsif (e = base.valueOf(vs = v.to_s.upcase) rescue nil)
|
325
|
+
e
|
326
|
+
else
|
327
|
+
raise ArgumentError, [message, v.to_s].join(': ')
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
def patch_table_descriptor! htd, props
|
332
|
+
props.each do |key, value|
|
333
|
+
next if key == :splits
|
334
|
+
|
335
|
+
if method = TABLE_PROPERTIES[key] && TABLE_PROPERTIES[key][:set]
|
336
|
+
htd.send method, value
|
337
|
+
elsif key.is_a?(String)
|
338
|
+
htd.setValue key, value.to_s
|
339
|
+
else
|
340
|
+
raise ArgumentError, "Invalid table property: #{key}" unless method
|
341
|
+
end
|
342
|
+
end
|
343
|
+
htd
|
344
|
+
end
|
345
|
+
|
346
|
+
def _alter props, bang, &block
|
347
|
+
raise ArgumentError, ":split not supported" if props[:splits]
|
348
|
+
with_admin do |admin|
|
349
|
+
htd = admin.get_table_descriptor(@name.to_java_bytes)
|
350
|
+
patch_table_descriptor! htd, props
|
351
|
+
while_disabled(admin) do
|
352
|
+
admin.modifyTable @name.to_java_bytes, htd
|
353
|
+
wait_async_admin(admin, &block) if bang
|
354
|
+
end
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def _add_family name, opts, bang, &block
|
359
|
+
with_admin do |admin|
|
360
|
+
while_disabled(admin) do
|
361
|
+
admin.addColumn @name, hcd(name.to_s, opts)
|
362
|
+
wait_async_admin(admin, &block) if bang
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
def _alter_family name, opts, bang, &block
|
368
|
+
with_admin do |admin|
|
369
|
+
while_disabled(admin) do
|
370
|
+
admin.modifyColumn @name, hcd(name.to_s, opts)
|
371
|
+
wait_async_admin(admin, &block) if bang
|
372
|
+
end
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def _delete_family name, bang, &block
|
377
|
+
with_admin do |admin|
|
378
|
+
while_disabled(admin) do
|
379
|
+
admin.deleteColumn @name, name.to_s
|
380
|
+
wait_async_admin(admin, &block) if bang
|
381
|
+
end
|
382
|
+
end
|
383
|
+
end
|
384
|
+
|
385
|
+
def _add_coprocessor class_name, props, bang, &block
|
386
|
+
with_admin do |admin|
|
387
|
+
while_disabled(admin) do
|
388
|
+
|
389
|
+
htd = admin.get_table_descriptor(@name.to_java_bytes)
|
390
|
+
if props.empty?
|
391
|
+
htd.addCoprocessor class_name
|
392
|
+
else
|
393
|
+
path, priority, params = props.values_at :path, :priority, :params
|
394
|
+
params = Hash[ params.map { |k, v| [k.to_s, v.to_s] } ]
|
395
|
+
htd.addCoprocessor class_name, path, priority || Coprocessor::PRIORITY_USER, params
|
396
|
+
end
|
397
|
+
admin.modifyTable @name.to_java_bytes, htd
|
398
|
+
wait_async_admin(admin, &block) if bang
|
399
|
+
end
|
400
|
+
end
|
401
|
+
end
|
402
|
+
|
403
|
+
def _remove_coprocessor name, bang, &block
|
404
|
+
unless HTableDescriptor.respond_to?(:removeCoprocessor)
|
405
|
+
raise NotImplementedError, "org.apache.hadoop.hbase.HTableDescriptor.removeCoprocessor not implemented"
|
406
|
+
end
|
407
|
+
with_admin do |admin|
|
408
|
+
while_disabled(admin) do
|
409
|
+
htd = admin.get_table_descriptor(@name.to_java_bytes)
|
410
|
+
htd.removeCoprocessor name
|
411
|
+
admin.modifyTable @name.to_java_bytes, htd
|
412
|
+
wait_async_admin(admin, &block) if bang
|
413
|
+
end
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def _split split_keys, bang, &block
|
418
|
+
with_admin do |admin|
|
419
|
+
split_keys.each do |sk|
|
420
|
+
wait_until_all_regions_online admin
|
421
|
+
admin.split(@name.to_java_bytes, Util.to_bytes(sk))
|
422
|
+
|
423
|
+
if bang
|
424
|
+
wait_async_admin(admin, &block)
|
425
|
+
wait_until_all_regions_online admin
|
426
|
+
end
|
427
|
+
end
|
428
|
+
end
|
429
|
+
end
|
430
|
+
|
431
|
+
def wait_until_all_regions_online admin
|
432
|
+
# FIXME: progress reporting
|
433
|
+
cnt = 0
|
434
|
+
while !_regions(admin).map { |r| r[:online] }.all? { |e| e }
|
435
|
+
raise RuntimeError, "Not all regions are online" if cnt >= MAX_SPLIT_WAIT
|
436
|
+
cnt += 1
|
437
|
+
sleep 1
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end#Table
|
441
|
+
end#HBase
|
442
|
+
|