leveldb-jruby 1.0.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.
- checksums.yaml +7 -0
- data/README.md +49 -0
- data/lib/level_db.rb +291 -0
- data/lib/level_db/version.rb +5 -0
- data/lib/leveldb.rb +6 -0
- metadata +62 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 762997e6da547e45865379880266e7332bb00937
|
4
|
+
data.tar.gz: 02b22ff12bb76f80507c8ffcde25fbfd5cf0dc79
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9cb03e1463d9e69f547d1463169efae0034fea7cfd4ee1f058dafa0ed919a882feae7000ff920e10135c484df9ef9f5a30180f197b8c3f17d5c240a1cf1aacc9
|
7
|
+
data.tar.gz: cadeda50ae412916a5a0c78099a76ad83f5e1967b0e53ca9160cb037527d4c9642a9f481c41e471f7d4e14cc3fff4d7760396009785cb0bf8a32e5d163be40e1
|
data/README.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# LevelDB for JRuby
|
2
|
+
|
3
|
+
## Installation
|
4
|
+
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
gem 'leveldb-jruby', require: 'leveldb'
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
db = LevelDb.open('path/to/database')
|
13
|
+
|
14
|
+
# basic key operations
|
15
|
+
db.put('foo', 'bar')
|
16
|
+
puts db.get('foo') # => 'bar'
|
17
|
+
db.delete('foo')
|
18
|
+
|
19
|
+
# iterating over a range of keys
|
20
|
+
10.times { |i| db.put("foo#{i.to_s.rjust(2, '0')}", i.to_s) }
|
21
|
+
db.each(from: 'foo', to: 'foo08') do |key, value|
|
22
|
+
puts "#{key} => #{value}"
|
23
|
+
end
|
24
|
+
|
25
|
+
# batch mutations
|
26
|
+
db.batch do |batch|
|
27
|
+
batch.put('foo', 'bar')
|
28
|
+
batch.delete('bar')
|
29
|
+
end
|
30
|
+
|
31
|
+
# read from a snapshot
|
32
|
+
db.put('foo', 'bar')
|
33
|
+
snapshot = db.snapshot
|
34
|
+
db.put('foo', 'baz')
|
35
|
+
puts snapshot.get('foo') # => 'bar'
|
36
|
+
puts db.get('foo') # => 'baz'
|
37
|
+
```
|
38
|
+
|
39
|
+
## Contributing
|
40
|
+
|
41
|
+
1. Fork it
|
42
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
43
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
44
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
45
|
+
5. Create new Pull Request
|
46
|
+
|
47
|
+
## License
|
48
|
+
|
49
|
+
http://opensource.org/licenses/BSD-3-Clause
|
data/lib/level_db.rb
ADDED
@@ -0,0 +1,291 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'leveldbjni-jars'
|
4
|
+
|
5
|
+
|
6
|
+
module LevelDb
|
7
|
+
module Library
|
8
|
+
include_package 'org.iq80.leveldb'
|
9
|
+
include_package 'org.fusesource.leveldbjni'
|
10
|
+
|
11
|
+
module Internal
|
12
|
+
include_package 'org.fusesource.leveldbjni.internal'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.open(path, options={})
|
17
|
+
Db.new(Library::JniDBFactory.factory.open(java.io.File.new(path), create_db_options(options)))
|
18
|
+
rescue Library::Internal::NativeDB::DBException => e
|
19
|
+
raise self::Error, e.message, e.backtrace
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.repair(path, options={})
|
23
|
+
Library::JniDBFactory.factory.repair(java.io.File.new(path), create_db_options(options))
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.destroy(path, options={})
|
28
|
+
Library::JniDBFactory.factory.destroy(java.io.File.new(path), create_db_options(options))
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.create_db_options(options)
|
33
|
+
options.each_with_object(Library::Options.new) do |(key, value), db_options|
|
34
|
+
if OPEN_OPTIONS.include?(key)
|
35
|
+
method_name, java_type = OPEN_OPTIONS[key]
|
36
|
+
db_options.java_send(method_name, [java_type], value)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
Error = Class.new(StandardError)
|
42
|
+
|
43
|
+
module Encoding
|
44
|
+
def encode_key(str)
|
45
|
+
return str unless str
|
46
|
+
str.to_java_bytes
|
47
|
+
end
|
48
|
+
|
49
|
+
def encode_value(str)
|
50
|
+
return str unless str
|
51
|
+
str.to_java_bytes
|
52
|
+
end
|
53
|
+
|
54
|
+
def decode_key(str)
|
55
|
+
String.from_java_bytes(str)
|
56
|
+
end
|
57
|
+
|
58
|
+
def decode_value(str)
|
59
|
+
String.from_java_bytes(str)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
module Crud
|
64
|
+
include Encoding
|
65
|
+
|
66
|
+
def get(key)
|
67
|
+
value = @db.get(encode_key(key))
|
68
|
+
value && decode_value(value)
|
69
|
+
rescue java.lang.IllegalArgumentException => e
|
70
|
+
raise ArgumentError, e.message, e.backtrace
|
71
|
+
end
|
72
|
+
|
73
|
+
def put(key, value)
|
74
|
+
@db.put(encode_key(key), encode_value(value))
|
75
|
+
rescue java.lang.IllegalArgumentException => e
|
76
|
+
raise ArgumentError, e.message, e.backtrace
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete(key)
|
80
|
+
@db.delete(encode_key(key))
|
81
|
+
rescue java.lang.IllegalArgumentException => e
|
82
|
+
raise ArgumentError, e.message, e.backtrace
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
class Db
|
87
|
+
include Crud
|
88
|
+
|
89
|
+
def initialize(db)
|
90
|
+
@db = db
|
91
|
+
end
|
92
|
+
|
93
|
+
def close
|
94
|
+
@db.close
|
95
|
+
end
|
96
|
+
|
97
|
+
def batch(&block)
|
98
|
+
batch = @db.create_write_batch
|
99
|
+
begin
|
100
|
+
yield Batch.new(batch)
|
101
|
+
@db.write(batch)
|
102
|
+
ensure
|
103
|
+
batch.close
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def each(options={}, &block)
|
108
|
+
cursor = Cursor.new(@db.iterator, options)
|
109
|
+
cursor.each(&block) if block_given?
|
110
|
+
cursor
|
111
|
+
end
|
112
|
+
|
113
|
+
def snapshot
|
114
|
+
Snapshot.new(@db)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
module LazyEnumerable
|
119
|
+
include Enumerable
|
120
|
+
|
121
|
+
def map(&transform)
|
122
|
+
LazyMap.new(self, &transform)
|
123
|
+
end
|
124
|
+
|
125
|
+
def select(&filter)
|
126
|
+
LazySelect.new(self, &filter)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
class LazyMap
|
131
|
+
include LazyEnumerable
|
132
|
+
|
133
|
+
def initialize(enum, &transform)
|
134
|
+
@enum = enum
|
135
|
+
@transform = transform
|
136
|
+
end
|
137
|
+
|
138
|
+
def each(&block)
|
139
|
+
if block
|
140
|
+
@enum.each do |element|
|
141
|
+
block.call(@transform.call(element))
|
142
|
+
end
|
143
|
+
end
|
144
|
+
self
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
class LazySelect
|
149
|
+
include LazyEnumerable
|
150
|
+
|
151
|
+
def initialize(enum, &filter)
|
152
|
+
@enum = enum
|
153
|
+
@filter = filter
|
154
|
+
end
|
155
|
+
|
156
|
+
def each(&block)
|
157
|
+
if block
|
158
|
+
@enum.each do |element|
|
159
|
+
block.call(element) if @filter.call(element)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
self
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
class Cursor
|
167
|
+
include Encoding
|
168
|
+
include LazyEnumerable
|
169
|
+
|
170
|
+
def initialize(iterator, options={})
|
171
|
+
@iterator = iterator
|
172
|
+
@from = options[:from]
|
173
|
+
@to = options[:to]
|
174
|
+
@reverse = options[:reverse]
|
175
|
+
@limit = options[:limit]
|
176
|
+
rewind
|
177
|
+
end
|
178
|
+
|
179
|
+
def close
|
180
|
+
@iterator.close
|
181
|
+
end
|
182
|
+
|
183
|
+
def next
|
184
|
+
raise StopIteration unless next?
|
185
|
+
v, @next = @next, nil
|
186
|
+
v
|
187
|
+
end
|
188
|
+
|
189
|
+
def next?
|
190
|
+
@next = internal_next unless @next
|
191
|
+
!!@next
|
192
|
+
end
|
193
|
+
|
194
|
+
def each
|
195
|
+
return self unless block_given?
|
196
|
+
rewind
|
197
|
+
yield self.next while next?
|
198
|
+
close
|
199
|
+
self
|
200
|
+
end
|
201
|
+
|
202
|
+
def rewind
|
203
|
+
@next = nil
|
204
|
+
@started = false
|
205
|
+
@exhausted = false
|
206
|
+
@count = 0
|
207
|
+
end
|
208
|
+
|
209
|
+
private
|
210
|
+
|
211
|
+
def init
|
212
|
+
return if @started
|
213
|
+
@started = true
|
214
|
+
@count = 0
|
215
|
+
if @from
|
216
|
+
@iterator.seek(encode_key(@from))
|
217
|
+
unless @iterator.has_next
|
218
|
+
@iterator.seek_to_last
|
219
|
+
end
|
220
|
+
if @reverse && @iterator.has_prev && (entry = @iterator.peek_next) && decode_key(entry.key) > @from
|
221
|
+
@iterator.prev
|
222
|
+
end
|
223
|
+
elsif @reverse
|
224
|
+
@iterator.seek_to_last
|
225
|
+
else
|
226
|
+
@iterator.seek_to_first
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def internal_next
|
231
|
+
init
|
232
|
+
return nil if @exhausted || (@limit && @count >= @limit)
|
233
|
+
if (entry = @iterator.has_next && @iterator.peek_next)
|
234
|
+
key = decode_key(entry.key)
|
235
|
+
if @reverse
|
236
|
+
return nil if (@to && key < @to) || (@from && @from < key)
|
237
|
+
@exhausted = !@iterator.has_prev
|
238
|
+
@exhausted || @iterator.prev
|
239
|
+
else
|
240
|
+
return nil if (@to && key > @to) || (@from && @from > key)
|
241
|
+
@exhausted = !@iterator.has_next
|
242
|
+
@exhausted || @iterator.next
|
243
|
+
end
|
244
|
+
@count += 1
|
245
|
+
return key, decode_value(entry.value)
|
246
|
+
end
|
247
|
+
rescue NativeException
|
248
|
+
raise
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class Snapshot
|
253
|
+
include Encoding
|
254
|
+
|
255
|
+
def initialize(db)
|
256
|
+
@db = db
|
257
|
+
@snapshot = @db.snapshot
|
258
|
+
@read_options = Library::ReadOptions.new
|
259
|
+
@read_options.snapshot(@snapshot)
|
260
|
+
end
|
261
|
+
|
262
|
+
def get(key)
|
263
|
+
value = @db.get(encode_key(key), @read_options)
|
264
|
+
value && decode_value(value)
|
265
|
+
end
|
266
|
+
|
267
|
+
def close
|
268
|
+
@snapshot.close
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
class Batch
|
273
|
+
include Crud
|
274
|
+
|
275
|
+
def initialize(batch)
|
276
|
+
@db = batch
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
private
|
281
|
+
|
282
|
+
OPEN_OPTIONS = {
|
283
|
+
:create_if_missing => [:createIfMissing, Java::boolean],
|
284
|
+
:error_if_exists => [:errorIfExists, Java::boolean],
|
285
|
+
:paranoid_checks => [:paranoidChecks, Java::boolean],
|
286
|
+
:write_buffer_size => [:writeBufferSize, Java::int],
|
287
|
+
:max_open_files => [:maxOpenFiles, Java::int],
|
288
|
+
:block_restart_interval => [:blockRestartInterval, Java::int],
|
289
|
+
:block_size => [:blockSize, Java::int],
|
290
|
+
}.freeze
|
291
|
+
end
|
data/lib/leveldb.rb
ADDED
metadata
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: leveldb-jruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Theo Hultberg
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ~>
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: 1.8.0
|
19
|
+
name: leveldbjni-jars
|
20
|
+
prerelease: false
|
21
|
+
type: :runtime
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.8.0
|
27
|
+
description: LevelDB for JRuby over JNI
|
28
|
+
email:
|
29
|
+
- theo@iconara.net
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- lib/level_db.rb
|
36
|
+
- lib/level_db/version.rb
|
37
|
+
- lib/leveldb.rb
|
38
|
+
homepage: http://github.com/iconara/leveldb-jruby
|
39
|
+
licenses:
|
40
|
+
- BSD 3-Clause License
|
41
|
+
metadata: {}
|
42
|
+
post_install_message:
|
43
|
+
rdoc_options: []
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: '0'
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 2.2.2
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: LevelDB for JRuby
|
62
|
+
test_files: []
|