hbase-jruby 0.6.3-java → 0.6.4-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +23 -0
- data/lib/hbase-jruby/hbase.rb +10 -5
- data/lib/hbase-jruby/table.rb +16 -13
- data/lib/hbase-jruby/table/mutation.rb +2 -0
- data/lib/hbase-jruby/util.rb +10 -0
- data/lib/hbase-jruby/version.rb +1 -1
- data/test/test_hbase.rb +6 -6
- data/test/test_table.rb +15 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f36f9ad6226b500c087ad5a8ffc9f294c738752e
|
4
|
+
data.tar.gz: 23ac26035d0054188538e115d899c191dd803776
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cb25e98c711400af4e3eda1f91efbc0ca2a145f0c213384ea7da2bb45d4b98f6511381dee30c0a606faf9c1f10948aff5996d6c447cfc0acb41d98d71cd9349c
|
7
|
+
data.tar.gz: 58a59bf73bf759718bd58063af461cee14ece10de17cd40634b81dbf26a6406fa3d8dc608a842fde314bb42a74a537c9965e3073edb368e12f34b6961e1445dc
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,29 @@
|
|
1
1
|
Changelog
|
2
2
|
=========
|
3
3
|
|
4
|
+
0.6.4
|
5
|
+
-----
|
6
|
+
|
7
|
+
### Performance improvement (experimental)
|
8
|
+
|
9
|
+
`HBase::Table` instance can be set up to cache the interpretations of the
|
10
|
+
column keys using thread-locals which can lead to 3-times faster Put
|
11
|
+
generation in tight loops.
|
12
|
+
|
13
|
+
```ruby
|
14
|
+
table = hbase[:my_table, cache: true]
|
15
|
+
# ...
|
16
|
+
table.close
|
17
|
+
```
|
18
|
+
|
19
|
+
However, the option is off by default because of the following issues:
|
20
|
+
|
21
|
+
1. You should not use it with the tables with unlimited number of columns.
|
22
|
+
2. Caching does not keep track of the updates of the schema. If you change the
|
23
|
+
schema of an `HBase` object after you created an `HBase::Table` object with
|
24
|
+
the cache turned on from it, the object may hold stale information on the
|
25
|
+
types of the columns. `HBase::Table#close` method will clean up the cache.
|
26
|
+
|
4
27
|
0.6.3
|
5
28
|
-----
|
6
29
|
|
data/lib/hbase-jruby/hbase.rb
CHANGED
@@ -9,6 +9,7 @@ class HBase
|
|
9
9
|
attr_reader :config, :schema
|
10
10
|
|
11
11
|
include Admin
|
12
|
+
include HBase::Util
|
12
13
|
|
13
14
|
# @overload HBase.log4j=(filename)
|
14
15
|
# Configure Log4j logging with the given file
|
@@ -99,7 +100,7 @@ class HBase
|
|
99
100
|
end
|
100
101
|
end
|
101
102
|
|
102
|
-
# Closes
|
103
|
+
# Closes the connection, and clean up thread-local cache
|
103
104
|
# @return [nil]
|
104
105
|
def close
|
105
106
|
@mutex.synchronize do
|
@@ -117,6 +118,10 @@ class HBase
|
|
117
118
|
end if use_table_pool?
|
118
119
|
end
|
119
120
|
end
|
121
|
+
|
122
|
+
thread_local.delete self
|
123
|
+
|
124
|
+
nil
|
120
125
|
end
|
121
126
|
|
122
127
|
# Returns whether if the connection is closed
|
@@ -128,25 +133,25 @@ class HBase
|
|
128
133
|
# Returns the list of HBase::Table instances
|
129
134
|
# @return [Array<HBase::Table>]
|
130
135
|
def tables
|
131
|
-
check_closed
|
132
136
|
table_names.map { |tn| table(tn) }
|
133
137
|
end
|
134
138
|
|
135
139
|
# Returns the list of table names
|
136
140
|
# @return [Array<String>]
|
137
141
|
def table_names
|
138
|
-
check_closed
|
139
142
|
with_admin { |admin| admin.list_tables.map(&:name_as_string) }
|
140
143
|
end
|
141
144
|
alias list table_names
|
142
145
|
|
143
146
|
# Creates an HBase::Table instance for the specified name
|
144
147
|
# @param [#to_s] table_name The name of the table
|
148
|
+
# @param [Hash] opts Options
|
149
|
+
# @option opts [Boolean] :cache Use thread-local cache (default: false)
|
145
150
|
# @return [HBase::Table]
|
146
|
-
def table table_name
|
151
|
+
def table table_name, opts = {}
|
147
152
|
check_closed
|
148
153
|
|
149
|
-
ht = HBase::Table.send :new, self, @config, table_name
|
154
|
+
ht = HBase::Table.send :new, self, @config, table_name, opts[:cache]
|
150
155
|
|
151
156
|
if block_given?
|
152
157
|
yield ht
|
data/lib/hbase-jruby/table.rb
CHANGED
@@ -21,23 +21,16 @@ class Table
|
|
21
21
|
check_closed
|
22
22
|
|
23
23
|
# [:hbase_jruby][HBase connection][Table name]
|
24
|
-
|
25
|
-
unless local_htables = local_vars[@hbase]
|
26
|
-
local_htables = local_vars[@hbase] = {}
|
27
|
-
end
|
28
|
-
local_htables[@name] ||= @hbase.send :get_htable, @name
|
24
|
+
thread_local(@hbase, @name_sym)[:htable] ||= @hbase.send(:get_htable, @name)
|
29
25
|
end
|
30
26
|
|
31
|
-
#
|
27
|
+
# Clean up thread-locals
|
32
28
|
# Generally this is not required unless you use unlimited number of threads
|
33
29
|
# @return [nil]
|
34
30
|
def close
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
(t = t[@hbase]) &&
|
39
|
-
(t = t.delete @name) &&
|
40
|
-
t.close
|
31
|
+
hash = thread_local(@hbase).delete(@name_sym)
|
32
|
+
hash[:htable].close if hash && hash[:htable]
|
33
|
+
nil
|
41
34
|
end
|
42
35
|
|
43
36
|
# Returns whether if the connection is closed
|
@@ -320,13 +313,23 @@ class Table
|
|
320
313
|
@hbase.schema.lookup_and_parse @name_sym, col, expect_cq
|
321
314
|
end
|
322
315
|
|
316
|
+
# @private
|
317
|
+
module ThreadLocalCache
|
318
|
+
def lookup_and_parse col, expect_cq
|
319
|
+
thread_local(@hbase, @name_sym, :columns)[col] ||=
|
320
|
+
@hbase.schema.lookup_and_parse(@name_sym, col, expect_cq)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
323
324
|
private
|
324
|
-
def initialize hbase, config, name
|
325
|
+
def initialize hbase, config, name, cache
|
325
326
|
@hbase = hbase
|
326
327
|
@config = config
|
327
328
|
@name = name.to_s
|
328
329
|
@name_sym = name.to_sym
|
329
330
|
@mutation = Mutation.new(self)
|
331
|
+
|
332
|
+
extend ThreadLocalCache if cache
|
330
333
|
end
|
331
334
|
|
332
335
|
def check_closed
|
data/lib/hbase-jruby/util.rb
CHANGED
@@ -194,6 +194,16 @@ private
|
|
194
194
|
raise ArgumentError, "Invalid time format"
|
195
195
|
end
|
196
196
|
end
|
197
|
+
|
198
|
+
# XXX Why am I doing this instead of using inject (reduce)?
|
199
|
+
# Because inject is around 25% slower, and this method is used in tight loops
|
200
|
+
def thread_local key1 = nil, key2 = nil, key3 = nil
|
201
|
+
obj = Thread.current[:hbase_jruby] ||= {}
|
202
|
+
obj = obj[key1] ||= {} if key1
|
203
|
+
obj = obj[key2] ||= {} if key2
|
204
|
+
obj = obj[key3] ||= {} if key3
|
205
|
+
obj
|
206
|
+
end
|
197
207
|
end#Util
|
198
208
|
end#HBase
|
199
209
|
|
data/lib/hbase-jruby/version.rb
CHANGED
data/test/test_hbase.rb
CHANGED
@@ -26,7 +26,7 @@ class TestHBase < TestHBaseJRubyBase
|
|
26
26
|
table.exists?
|
27
27
|
assert @hbase.list.is_a?(Array)
|
28
28
|
|
29
|
-
assert_equal table.htable, Thread.current[:hbase_jruby][@hbase][TABLE]
|
29
|
+
assert_equal table.htable, Thread.current[:hbase_jruby][@hbase][TABLE.to_sym][:htable]
|
30
30
|
|
31
31
|
assert !@hbase.closed?
|
32
32
|
assert !table.closed?
|
@@ -51,7 +51,7 @@ class TestHBase < TestHBaseJRubyBase
|
|
51
51
|
# Reconnect and check
|
52
52
|
@hbase = connect
|
53
53
|
table = @hbase[TABLE]
|
54
|
-
assert_equal table.htable, Thread.current[:hbase_jruby][@hbase][TABLE]
|
54
|
+
assert_equal table.htable, Thread.current[:hbase_jruby][@hbase][TABLE.to_sym][:htable]
|
55
55
|
|
56
56
|
# FIXME: Connection is closed, we have to update @table object
|
57
57
|
@table = @hbase.table(TABLE)
|
@@ -83,9 +83,9 @@ class TestHBase < TestHBaseJRubyBase
|
|
83
83
|
table = hbase2[TABLE]
|
84
84
|
assert_nil Thread.current[:hbase_jruby][hbase2]
|
85
85
|
|
86
|
-
table.htable
|
86
|
+
ht = table.htable
|
87
87
|
# Thread-local htable cache has now been created
|
88
|
-
|
88
|
+
assert_equal ht, Thread.current[:hbase_jruby][hbase2][TABLE.to_sym][:htable]
|
89
89
|
|
90
90
|
sleeping = {}
|
91
91
|
mutex = Mutex.new
|
@@ -99,8 +99,8 @@ class TestHBase < TestHBaseJRubyBase
|
|
99
99
|
sleep 0.1 while mutex.synchronize { sleeping.length } < 4
|
100
100
|
threads.each do |t|
|
101
101
|
assert t[:htable]
|
102
|
-
assert t[:hbase_jruby][hbase2][TABLE]
|
103
|
-
assert_equal t[:htable], t[:hbase_jruby][hbase2][TABLE]
|
102
|
+
assert t[:hbase_jruby][hbase2][TABLE.to_sym]
|
103
|
+
assert_equal t[:htable], t[:hbase_jruby][hbase2][TABLE.to_sym][:htable]
|
104
104
|
|
105
105
|
t.kill
|
106
106
|
end
|
data/test/test_table.rb
CHANGED
@@ -410,7 +410,7 @@ class TestTable < TestHBaseJRubyBase
|
|
410
410
|
|
411
411
|
assert_equal true, @table.check(rk, a => 100).delete(c, ts, (ts - 2000).to_i, 'cf2')
|
412
412
|
assert_equal 1, @table.versions(:all).get(rk).to_H[:c].length
|
413
|
-
assert_equal
|
413
|
+
assert_equal((ts - 1000).to_i, @table.versions(:all).get(rk).to_H[:c].keys.first / 1000)
|
414
414
|
assert_equal nil, @table.get(rk)[d]
|
415
415
|
|
416
416
|
assert_equal true, @table.check(rk, a => 100).delete
|
@@ -541,5 +541,19 @@ class TestTable < TestHBaseJRubyBase
|
|
541
541
|
assert e.java_exception.is_a?(java.lang.Exception)
|
542
542
|
end
|
543
543
|
end
|
544
|
+
|
545
|
+
def test_thread_local_cache
|
546
|
+
cached = @hbase[TABLE, :cache => true]
|
547
|
+
not_cached = @hbase[TABLE]
|
548
|
+
|
549
|
+
cached.put next_rowkey, 'cf1:abc' => 100
|
550
|
+
not_cached.put next_rowkey, 'cf1:def' => 100
|
551
|
+
|
552
|
+
assert_equal ['cf1:abc'], Thread.current[:hbase_jruby][@hbase][TABLE.to_sym][:columns].keys
|
553
|
+
cached.close
|
554
|
+
|
555
|
+
# FIXME closing not_cached will also remove the cache
|
556
|
+
assert_nil Thread.current[:hbase_jruby][@hbase][TABLE.to_sym]
|
557
|
+
end
|
544
558
|
end
|
545
559
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hbase-jruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: java
|
6
6
|
authors:
|
7
7
|
- Junegunn Choi
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-12-
|
11
|
+
date: 2014-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: test-unit
|