rocksdb-ruby 0.2.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 02a4d4a14d208c82b4350ad74137d5dc61787981
4
- data.tar.gz: 11cb366cd0278dc76275ff163f450e8e18564a6d
2
+ SHA256:
3
+ metadata.gz: 3a31d0881ac039ce8fc05c6aa47b34984fef049367e797027dc4de381b618bcc
4
+ data.tar.gz: 713b878614320830014a92f0390ddf42f6a40803cb746f9d8b56bed32a14bdea
5
5
  SHA512:
6
- metadata.gz: 67921bce1b5f49bee1861089067ee59a9380913356e20455b8135dfe498c2799c5c9b88802221709aa09522442504c1a4e2c2a13d25e806af18c98184f552a0c
7
- data.tar.gz: 0cdcbd2d5aa177d1c85db02ac03fe2f83562a9510357228ee36ce699fe527d1e6e4243aaa5d311a09b63c3775bcab19e6c71094c4cd1aacbfe5a36fca70c0ffc
6
+ metadata.gz: 3acd74eef6bfa29bb6c972225ec8d5cfa4ab9617e3cf0663c152e0c4b472bbb70bee993cd19b65ec058568857df5d39538d3799996293d6b6055c8a63e9ffd0d
7
+ data.tar.gz: d9ca30a13ae84da30d347951e4951eb98896e38eb61211ed93cf733fd5f301d7500ad4c2167207085a636a4251561fa972e88174549d545e7210315a9f7dc1f1
data/.gitignore CHANGED
@@ -15,3 +15,7 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ ext/**/*.o
19
+ ext/**/Makefile
20
+ ext/**/*.log
21
+ ext/**/*.bundle
data/.travis.yml CHANGED
@@ -1,22 +1,62 @@
1
1
  language: ruby
2
+ script: bundle exec rake spec
3
+
2
4
  rvm:
3
- - 2.4.0
4
- script: bundle exec rake spec || ( cat ext/rocksdb/mkmf.log && /bin/false )
5
+ - 2.4
6
+ - 2.5
7
+ - 2.6
8
+ - 2.7
9
+ - 3.0
10
+
11
+ os:
12
+ - linux
13
+ - osx
14
+
15
+ # We can use this matrix to pick supported versions
16
+ # https://repology.org/project/rocksdb/versions
17
+ jobs:
18
+ include:
19
+ - os: linux
20
+ env: ROCKSDB_VERSION=6.3.6
21
+ - os: linux
22
+ env: ROCKSDB_VERSION=5.17.2
23
+ - os: linux
24
+ env: ROCKSDB_VERSION=4.5.1
25
+ - os: osx
26
+ env: ROCKSDB_VERSION=5.18.3 ROCKSDB_VERSION_COMMIT=d38e4b445ea1525fba69b1d7b88dc63e9faaa21b
27
+ - os: osx
28
+ env: ROCKSDB_VERSION=6.1.2 ROCKSDB_VERSION_COMMIT=6e35266c1f6b7bab9ed4371e5cf9f1cfca0566b7
29
+
30
+ cache:
31
+ ccache: true
32
+ bundler: true
33
+ directories:
34
+ - /home/travis/.ccache
35
+
36
+ addons:
37
+ apt:
38
+ sources:
39
+ - sourceline: 'ppa:ubuntu-toolchain-r/test'
40
+ packages:
41
+ - gdb
42
+ - gcc-8
43
+ - g++-8
44
+ - libbz2-dev
45
+ - zlib1g-dev
46
+ - libgflags-dev
47
+ - libsnappy-dev
48
+
49
+ before_script:
50
+ # enable core dumps
51
+ - ulimit -c unlimited -S
5
52
 
6
53
  before_install:
7
- - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
8
- - sudo apt-get update -qq
9
- - sudo apt-get install gcc-6 g++-6 libsnappy-dev zlib1g-dev libbz2-dev -qq
10
- - export CXX="g++-6" CC="gcc-6"
11
- - sudo ln -s /usr/bin/gcc-6 /usr/local/bin/gcc
12
- - sudo ln -s /usr/bin/g++-6 /usr/local/bin/g++
13
54
  - gem install bundler
14
55
 
15
56
  install:
16
- - git clone https://github.com/facebook/rocksdb.git /tmp/rocksdb
17
- - pushd /tmp/rocksdb
18
- - make clean
19
- - make shared_lib
20
- - popd
21
- - export ROCKSDB_RUBY_BUILD_PARAMS="--with-rocksdb-dir=/tmp/rocksdb --with-rocksdb-lib=/tmp/rocksdb"
22
- - bundle install
57
+ - export ROCKSDB_FOLDER=/tmp/rocksdb/
58
+ - export ROCKSDB_RUBY_BUILD_PARAMS="--with-rocksdb-dir=$ROCKSDB_FOLDER --with-rocksdb-lib=$ROCKSDB_FOLDER"
59
+ - ./.travis/install.sh
60
+
61
+ after_failure:
62
+ - ./.travis/after_failure.sh
@@ -0,0 +1,16 @@
1
+ echo "---- mmkf.log ----"
2
+ cat ext/rocksdb/mkmf.log
3
+ echo "---- makefile ----"
4
+ cat ext/rocksdb/Makefile
5
+
6
+ if [ $TRAVIS_OS_NAME = 'linux' ]; then
7
+ # Show core dump contents and build configuration if any
8
+ COREFILE=$(find . -maxdepth 1 -name "core*" | head -n 1)
9
+ CORE_PROG=$(which ruby)
10
+ echo "---- gdb $CORE_PROG -c "$COREFILE" ----"
11
+ if [[ -f "$COREFILE" ]]; then
12
+ gdb $CORE_PROG -c "$COREFILE" -ex "thread apply all bt full" -ex "set pagination 0" -batch
13
+ fi
14
+ else
15
+ echo "Can't inspect coredump on ${TRAVIS_OS_NAME}"
16
+ fi
@@ -0,0 +1,55 @@
1
+ #!/bin/bash
2
+
3
+ # Fail if anything fails
4
+ set -e
5
+
6
+ if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
7
+ # BUG: https://discourse.brew.sh/t/octave-require-relative-problem/6043
8
+ # BUG: https://travis-ci.community/t/homebrew-syntax-error/5623
9
+ export HOMEBREW_NO_AUTO_UPDATE=1
10
+
11
+ if [[ -z "${ROCKSDB_VERSION}" ]]; then
12
+ echo "Brewing latest available version"
13
+ brew install "rocksdb"
14
+ else
15
+ BREW_CORE_URI="https://raw.githubusercontent.com/Homebrew/homebrew-core"
16
+ FORMULA_URI="${BREW_CORE_URI}/${ROCKSDB_VERSION_COMMIT}/Formula/rocksdb.rb"
17
+ echo "Installing ${ROCKSDB_VERSION} from ${ROCKSDB_VERSION_COMMIT}"
18
+ brew install "${FORMULA_URI}"
19
+ brew switch rocksdb "${ROCKSDB_VERSION}"
20
+ fi
21
+
22
+ echo "Building bundle"
23
+ bundle install
24
+ elif [[ $TRAVIS_OS_NAME == 'linux' ]]; then
25
+ export PATH="/usr/lib/ccache/:$PATH"
26
+
27
+ if [[ -z "${ROCKSDB_VERSION}" ]]; then
28
+ echo "Building from rocksdb master in ${ROCKSDB_FOLDER}"
29
+ git clone -b "master" --single-branch --depth 1 https://github.com/facebook/rocksdb.git $ROCKSDB_FOLDER
30
+ else
31
+ echo "Building ${ROCKSDB_VERSION} in ${ROCKSDB_FOLDER}"
32
+ git clone -b "v$ROCKSDB_VERSION" --single-branch --depth 1 https://github.com/facebook/rocksdb.git $ROCKSDB_FOLDER
33
+ fi
34
+
35
+ pushd $ROCKSDB_FOLDER
36
+ ccache -s
37
+
38
+ if [[ $DEBUG_LEVEL == '1' ]]; then
39
+ echo "Building with DEBUG_LEVEL=1"
40
+ # TODO: I think it's better to try to satisfy all the rocksdb checks
41
+ make -j4 shared_lib DEBUG_LEVEL=1
42
+ else
43
+ make -j4 shared_lib
44
+ fi
45
+
46
+ ccache -s
47
+ popd
48
+
49
+ echo "Building bundle with params:"
50
+ echo "${ROCKSDB_RUBY_BUILD_PARAMS}"
51
+ bundle install
52
+ else
53
+ echo "Unsupported OS ${TRAVIS_OS_NAME}"
54
+ exit 1
55
+ fi
data/README.md CHANGED
@@ -11,61 +11,429 @@ This gem contains Ruby bindings so that you can use it from your Ruby process.
11
11
 
12
12
  ## Installation
13
13
 
14
- First install rocksdb.
14
+ First, install rocksdb: https://github.com/facebook/rocksdb/blob/master/INSTALL.md
15
15
 
16
16
  Add this line to your application's Gemfile:
17
17
 
18
- gem 'rocksdb-ruby'
18
+ ```ruby
19
+ gem 'rocksdb-ruby'
20
+ ```
19
21
 
20
22
  And then execute:
21
23
 
22
- $ bundle
24
+ ```sh
25
+ $ bundle
26
+ ```
23
27
 
24
28
  Or install it yourself as:
25
29
 
26
- $ gem install rocksdb-ruby
30
+ ```sh
31
+ $ gem install rocksdb-ruby
32
+ ```
33
+
34
+ `rocksdb-ruby` is tested against Ruby 2.4, 2.5 and 2.6 on Linux and macOS platforms. However, it might work on other platforms.
35
+
36
+ `rocksdb-ruby` supports rocksb 4.5.1 and later. It is tested against master branch with all supported ruby version. It is also tested against few specific version, available in popular distributions. Check `.travis.yml` for details.
37
+
38
+ JRuby, TruffleRuby and Rubinius are not supported at the moment.
27
39
 
28
40
  ## Usage
29
41
 
42
+
43
+ ### Open database
44
+
45
+ First, you need to open database. Use `open` method and pass path to database
46
+ root as first argument. By default, it will create path if missing.
47
+
48
+ ```ruby
49
+
50
+ require "rocksdb"
51
+
52
+ # Open for reads and writes
53
+ rocksdb = RocksDB.open "/tmp/file1"
54
+ ```
55
+
56
+ You can pass RocksDB options as second argument:
57
+
58
+ ```ruby
59
+
60
+ require "rocksdb"
61
+
62
+ # Open for reads and writes
63
+ rocksdb = RocksDB.open "/tmp/file2", compression: "kNoCompression"
64
+ ```
65
+
66
+ Or you can pass raw Option String:
67
+
68
+ ```ruby
69
+
70
+ require "rocksdb"
71
+
72
+ # Open for reads and writes
73
+ rocksdb = RocksDB.open "/tmp/file2", "compression=kNoCompression"
74
+ ```
75
+
76
+ Read more about Option Sting: https://github.com/facebook/rocksdb/wiki/Option-String-and-Option-Map#option-string
77
+
78
+ ### Basic reads and writes
79
+
80
+ You can read and write keys using `put` and `get` methods:
81
+
82
+ ```ruby
83
+
84
+ require "rocksdb"
85
+
86
+ # Open for reads and writes
87
+ rocksdb = RocksDB.open "/tmp/file3"
88
+
89
+ # Store string `World` under key `Hello`
90
+ rocksdb.put "Hello", "World"
91
+
92
+ # Read a value stored under key `Hello`
93
+ puts rocksdb.get "Hello"
94
+ # => World
95
+ ```
96
+
97
+ You can also use Hash-like methods `[]` and `[]=`
98
+
99
+ ```ruby
100
+
101
+ require "rocksdb"
102
+
103
+ # Open for reads and writes
104
+ rocksdb = RocksDB.open "/tmp/file4"
105
+
106
+ # Store string `World` under key `Hello`
107
+ rocksdb["Hello"] = "World"
108
+
109
+ # Read a value stored under key `Hello`
110
+ puts rocksdb["Hello"]
111
+ # => World
112
+ ```
113
+
114
+ If key does not exists, RocksDB will return nil:
115
+
116
+ ```ruby
117
+
118
+ require "rocksdb"
119
+
120
+ # Open for reads and writes
121
+ rocksdb = RocksDB.open "/tmp/file5"
122
+
123
+ # Try to read a key, that does not exists
124
+ result = rocksdb.get "Missing Key"
125
+
126
+ if !result
127
+ puts "Key not found!"
128
+ end
129
+
130
+ # => Key not found
131
+ ```
132
+
133
+ If you want to get multiple keys at the same time, you can use `get` with multiple arguments:
134
+
135
+ ```ruby
136
+
137
+ require "rocksdb"
138
+
139
+ # Open for reads and writes
140
+ rocksdb = RocksDB.open "/tmp/file6"
141
+
142
+ rocksdb.put "First Key", "First Value"
143
+ rocksdb.put "Second Key", "Second Value"
144
+ rocksdb.put "Third Key", "Third Value"
145
+
146
+ # If key does not exists, you'll get nil
147
+ values = rocksdb.get "Second Key", "Imaginary Key", "Third Key"
148
+
149
+ puts values
150
+ # => ["Second Value", nil, "Third Value"]
151
+ ```
152
+
153
+ You can check, if key exists:
154
+
155
+ ```ruby
156
+
157
+ require "rocksdb"
158
+
159
+ # Open for reads and writes
160
+ rocksdb = RocksDB.open "/tmp/file7"
161
+
162
+ rocksdb.put "Real Key", "Real Value"
163
+
164
+ rocksdb.exists? "Real Key"
165
+ # => true
166
+
167
+ rocksdb.exists? "Imaginary Key"
168
+ # => false
169
+ ```
170
+
171
+ And you can delete keys, when not needed:
172
+
173
+ ```ruby
174
+
175
+ require "rocksdb"
176
+
177
+ # Open for reads and writes
178
+ rocksdb = RocksDB.open "/tmp/file8"
179
+
180
+ rocksdb.put "Delete Me", "Memory"
181
+ rocksdb.exists? "Delete Me"
182
+ # => true
183
+ rocksdb.delete "Delete Me"
184
+ rocksdb.exists? "Delete Me"
185
+ # => false
186
+
187
+ rocksdb.get "Delete Me"
188
+ # => nil
189
+ ```
190
+
191
+ You can open RocksDB only for reading:
192
+
193
+ ```ruby
194
+
195
+ require "rocksdb"
196
+
197
+ # Open only for reading
198
+ rocksdb = RocksDB.open_readonly "/tmp/file9"
199
+
200
+ puts rocksdb.writable?
201
+ # => false
202
+
203
+ rocksdb.put "First Key", "First Value"
204
+
205
+ # => RocksDB::ReadOnly (database is read-only)
206
+ ```
207
+
208
+
209
+ ### Enumerable
210
+
211
+ You can enumerate over all values using `each` method. Note how values are sorted lexicographically by their keys:
212
+
213
+ ```ruby
214
+
30
215
  require "rocksdb"
31
216
 
32
- # Reads And Writes
33
- key = "test"
34
- value = "1"
35
- rocksdb = RocksDB::DB.new "/tmp/file"
36
- rocksdb.put(key, value)
37
- new_value = rocksdb.get(key)
38
- rocksdb.delete(key)
217
+ # Open for reads and writes
218
+ rocksdb = RocksDB.open "/tmp/file10"
219
+
220
+ rocksdb.put "One", "1"
221
+ rocksdb.put "Two", "2"
222
+ rocksdb.put "Three", "3"
223
+
224
+ rocksdb.each do |value|
225
+ puts value
226
+ end
227
+
228
+ # => 1
229
+ # => 3
230
+ # => 2
231
+ ```
232
+
233
+ Additionally, you can enumerate in reverse order with `reverse_each`:
234
+
235
+ ```ruby
236
+
237
+ require "rocksdb"
238
+
239
+ # Open for reads and writes
240
+ rocksdb = RocksDB.open "/tmp/file11"
241
+
242
+ rocksdb.put "One", "1"
243
+ rocksdb.put "Two", "2"
244
+ rocksdb.put "Three", "3"
245
+
246
+ rocksdb.reverse_each do |value|
247
+ puts value
248
+ end
249
+
250
+ # => 2
251
+ # => 3
252
+ # => 1
253
+ ```
254
+
255
+ You can enumerate over keys with `each_key` or in reverse order with `reverse_each_key`:
256
+
257
+ ```ruby
258
+
259
+ require "rocksdb"
260
+
261
+ # Open for reads and writes
262
+ rocksdb = RocksDB.open "/tmp/file12"
263
+
264
+ rocksdb.put "One", "1"
265
+ rocksdb.put "Two", "2"
266
+ rocksdb.put "Three", "3"
267
+
268
+ rocksdb.each_key do |key|
269
+ puts key
270
+ end
271
+
272
+ # => One
273
+ # => Three
274
+ # => Two
275
+
276
+ rocksdb.reverse_each_key do |key|
277
+ puts key
278
+ end
279
+
280
+ # => Two
281
+ # => Three
282
+ # => One
283
+ ```
284
+
285
+ You can enumerate over both keys and values with `each_pair` and in reverse order with `reverse_each_pair`:
286
+
287
+ ```ruby
288
+
289
+ require "rocksdb"
290
+
291
+ # Open for reads and writes
292
+ rocksdb = RocksDB.open "/tmp/file13"
293
+
294
+ rocksdb.put "One", "1"
295
+ rocksdb.put "Two", "2"
296
+ rocksdb.put "Three", "3"
297
+
298
+ rocksdb.each_pair do |key, value|
299
+ puts "#{key} = #{value}"
300
+ end
301
+
302
+ # => One = 1
303
+ # => Three = 3
304
+ # => Two = 2
305
+ ```
306
+
307
+ Additionally, you can enumerate over keys that start with a specific prefix with `each_prefix`:
308
+
309
+ ```ruby
310
+
311
+ require "rocksdb"
312
+
313
+ # Open for reads and writes
314
+ rocksdb = RocksDB.open "/tmp/file14"
315
+
316
+ rocksdb.put "my:1", "1"
317
+ rocksdb.put "my:2", "2"
318
+ rocksdb.put "your:3", "3"
319
+
320
+ rocksdb.each_prefix("my") do |key, value|
321
+ puts "#{key} = #{value}"
322
+ end
323
+
324
+ # => my:1 = 1
325
+ # => my:2 = 2
326
+ ```
327
+
328
+ Or you can scan over the ranges of keys with `each_range`. Note, range is `[start, limit]`:
329
+
330
+ ```ruby
331
+
332
+ require "rocksdb"
333
+
334
+ # Open for reads and writes
335
+ rocksdb = RocksDB.open "/tmp/file15"
336
+
337
+ 10.times do |count|
338
+ rocksdb.put "key:#{count}", "#{count}"
339
+ end
340
+
341
+ rocksdb.each_range("key:5", "key:7") do |key, value|
342
+ puts "#{key} = #{value}"
343
+ end
344
+
345
+ # => key:5 = 5
346
+ # => key:6 = 6
347
+ # => key:7 = 7
348
+ ```
349
+
350
+ ### Atomic Batches
351
+
352
+ You can use `RocksDB::Batch` to atomically insert big chunks of data.
353
+
354
+ ```ruby
355
+
356
+ require "rocksdb"
357
+
358
+ # Open for reads and writes
359
+ rocksdb = RocksDB.open "/tmp/file16"
39
360
 
40
- #Atomic Updates
41
361
  batch = RocksDB::Batch.new
362
+
42
363
  batch.delete("test:batch1")
43
364
  batch.put("test:batch2", "b")
365
+
44
366
  rocksdb.write(batch)
45
367
 
46
- #Iteration
47
- iterator = rocksdb.new_iterator
368
+ rocksdb.each_pair do |key, value|
369
+ puts "#{key} = #{value}"
370
+ end
371
+
372
+ # => test:batch2 = b
373
+ ```
374
+
375
+ Read more about RocksDB batches: https://github.com/facebook/rocksdb/wiki/Basic-Operations#atomic-updates
376
+
377
+ # Iterator
378
+
379
+ You can get RocksDB Iterator with `to_iterator` method to iterate over your data:
380
+
381
+ ```ruby
382
+
383
+ require "rocksdb"
384
+
385
+ # Open for reads and writes
386
+ rocksdb = RocksDB.open "/tmp/file16"
48
387
 
388
+ 10.times do |count|
389
+ rocksdb.put "key:#{count}", "#{count}"
390
+ end
391
+
392
+ # Get Iterator
393
+ iterator = rocksdb.to_iterator
394
+ # Seek to some position. You can also use seek("key") to
49
395
  iterator.seek_to_first
50
- while(iterator.valid)
51
- iterator.value
52
- iterator.key
396
+
397
+ while iterator.valid?
398
+ puts "#{iterator.value} = #{iterator.key}"
53
399
  iterator.next
54
400
  end
401
+
55
402
  iterator.close
403
+ ```
56
404
 
57
- #Block
58
- rocksdb.each do |data|
59
- puts data
60
- end
405
+ Supported methods:
406
+
407
+ * `seek(key)` seeks to closest key to given prefix at beginning
408
+ * `seek_to_first` seeks to the first key
409
+ * `seek_to_last` seeks to the last key
410
+ * `next` seeks to the next key
411
+ * `previous` seeks to the previous key
412
+ * `valid?` returns true if iterator can be iterated
413
+ * `close` closes iterator
414
+ * `key` returns current key
415
+ * `value` returns current value
416
+
417
+ Methods supported by rocksdb 4.11 and later:
418
+
419
+ * `seek_for_previous(key)`seeks to closest key to given prefix at end
420
+
421
+ ## Upgrade
422
+
423
+ When upgrading from `0.2` version, please note the following breaking changes:
61
424
 
62
- #Hash access
63
- rocksdb['key'] = data
64
- puts rocksdb['key']
425
+ * `multi_get` will return `nil` instead of empty string
426
+ * `RocksDB::DB.get_instance` is removed. Implement your own DB instance cache if needed
427
+ * `each_` methods now returns `Enumerator` instead of `RocksDB::Iterator`
65
428
 
66
-
67
- rocksdb.close
429
+ Also, there some things that are now deprecated and will be removed in future versions:
68
430
 
431
+ * `RocksDB::DBError` was deprecated and replaced with `RocksDB::Error`. Specific errors now have their own exception class: `ReadOnly`, `DatabaseClosed`, `IteratorClosed`, `StatusError`
432
+ * `is_open?` was replaced with `open?`
433
+ * `is_readonly?` was replaced with `writable?`
434
+ * `multi_get` was replaced with `get_many`
435
+ * `new_iterator` was replaced with `to_iterator`
436
+ * `Iterator#valid` was replaced with `Iterator#valid?`
69
437
 
70
438
  ## Contributing
71
439