hbase-jruby 0.1.6-java → 0.2.0-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -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 [org.apache.hadoop.hbase.client.HBaseAdmin]
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
- @htable_pool.close
50
- HConnectionManager.deleteConnection(@config, true)
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
- ht = HBase::Table.send :new, @config, @htable_pool, table_name
108
+ check_closed
109
+
110
+ ht = HBase::Table.send :new, self, @config, @htable_pool, table_name
70
111
 
71
112
  if block_given?
72
- begin
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
 
@@ -4,7 +4,7 @@
4
4
 
5
5
  <groupId>hbase-jruby</groupId>
6
6
  <artifactId>hbase-project</artifactId>
7
- <version>0.1.6</version>
7
+ <version>0.2</version>
8
8
  <packaging>jar</packaging>
9
9
 
10
10
  <name>hbase-jruby</name>
@@ -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 [HBase::Result] Yields each row in the scope
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
+