hbase-jruby 0.6.3-java → 0.6.4-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.
- 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
|