rocksdb-ruby 0.2.3 → 1.0.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e63a830799d975bd61b019413c022b2dd2c2b996
4
- data.tar.gz: 4629fb74bd9ff28fdcc4654656410b729033d3e0
3
+ metadata.gz: ff03f629257fdb8ac8848e41458d5d1eb585f815
4
+ data.tar.gz: acec6cb4441abdd687337be38eec30be8c74fb49
5
5
  SHA512:
6
- metadata.gz: 8cd31b6afd9fc8c84638b1e37325a753e1f2a4bde49e48697f993bcf65b71c6c480b89fde2ee303a3ec1ec9b52339081508809aef6be0a31ede97cf8747191da
7
- data.tar.gz: 4dec517e5bcc0d8c6b82c1c5a02c43643a9e0bd8e4fa1174d62730ed6c91e950e395957249e6adeb0b4bdb451faffe300b997c8ffe70a6b99c6f5c2337918cbc
6
+ metadata.gz: 7688c4b6bcbe355a87e23a4a28923ac9d6fac529330be380b3c7fbebec5b9b6517ae311bc52e7cc6dc85eb2f6954c5014e1c530b8e11b1729ea12561c1751a2a
7
+ data.tar.gz: fc91395d2ddee8543e1dcd438658ab147c21f9414855ece7649ef12ad87dc552cc5f2d46f3ef25653e701bdf420636712da4efb1131ce8b9ddc97e57d4f9a0c3
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
@@ -1,22 +1,60 @@
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
+
9
+ os:
10
+ - linux
11
+ - osx
12
+
13
+ # We can use this matrix to pick supported versions
14
+ # https://repology.org/project/rocksdb/versions
15
+ jobs:
16
+ include:
17
+ - os: linux
18
+ env: ROCKSDB_VERSION=6.3.6
19
+ - os: linux
20
+ env: ROCKSDB_VERSION=5.17.2
21
+ - os: linux
22
+ env: ROCKSDB_VERSION=4.5.1
23
+ - os: osx
24
+ env: ROCKSDB_VERSION=5.18.3 ROCKSDB_VERSION_COMMIT=d38e4b445ea1525fba69b1d7b88dc63e9faaa21b
25
+ - os: osx
26
+ env: ROCKSDB_VERSION=6.1.2 ROCKSDB_VERSION_COMMIT=6e35266c1f6b7bab9ed4371e5cf9f1cfca0566b7
27
+
28
+ cache:
29
+ ccache: true
30
+ bundler: true
31
+ directories:
32
+ - /home/travis/.ccache
33
+
34
+ addons:
35
+ apt:
36
+ sources:
37
+ - sourceline: 'ppa:ubuntu-toolchain-r/test'
38
+ packages:
39
+ - gdb
40
+ - gcc-8
41
+ - g++-8
42
+ - libbz2-dev
43
+ - zlib1g-dev
44
+ - libgflags-dev
45
+ - libsnappy-dev
46
+
47
+ before_script:
48
+ # enable core dumps
49
+ - ulimit -c unlimited -S
5
50
 
6
51
  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
52
  - gem install bundler
14
53
 
15
54
  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
55
+ - export ROCKSDB_FOLDER=/tmp/rocksdb/
56
+ - export ROCKSDB_RUBY_BUILD_PARAMS="--with-rocksdb-dir=$ROCKSDB_FOLDER --with-rocksdb-lib=$ROCKSDB_FOLDER"
57
+ - ./.travis/install.sh
58
+
59
+ after_failure:
60
+ - ./.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,7 +11,7 @@ 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
 
@@ -31,49 +31,410 @@ Or install it yourself as:
31
31
  $ gem install rocksdb-ruby
32
32
  ```
33
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.
39
+
34
40
  ## Usage
35
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
+
36
82
  ```ruby
37
- require "rocksdb"
38
83
 
39
- # Reads And Writes
40
- key = "test"
41
- value = "1"
42
- rocksdb = RocksDB::DB.new "/tmp/file"
43
- rocksdb.put(key, value)
44
- new_value = rocksdb.get(key)
45
- rocksdb.delete(key)
84
+ require "rocksdb"
46
85
 
47
- # Atomic Updates
48
- batch = RocksDB::Batch.new
49
- batch.delete("test:batch1")
50
- batch.put("test:batch2", "b")
51
- rocksdb.write(batch)
86
+ # Open for reads and writes
87
+ rocksdb = RocksDB.open "/tmp/file3"
52
88
 
53
- # Iteration
54
- iterator = rocksdb.new_iterator
89
+ # Store string `World` under key `Hello`
90
+ rocksdb.put "Hello", "World"
55
91
 
56
- iterator.seek_to_first
57
- while(iterator.valid)
58
- iterator.value
59
- iterator.key
60
- iterator.next
61
- end
62
- iterator.close
92
+ # Read a value stored under key `Hello`
93
+ puts rocksdb.get "Hello"
94
+ # => World
95
+ ```
63
96
 
64
- # Block
65
- rocksdb.each do |data|
66
- puts data
67
- end
97
+ You can also use Hash-like methods `[]` and `[]=`
68
98
 
69
- # Hash access
70
- rocksdb['key'] = data
71
- puts rocksdb['key']
99
+ ```ruby
100
+
101
+ require "rocksdb"
102
+
103
+ # Open for reads and writes
104
+ rocksdb = RocksDB.open "/tmp/file4"
72
105
 
106
+ # Store string `World` under key `Hello`
107
+ rocksdb["Hello"] = "World"
73
108
 
74
- rocksdb.close
109
+ # Read a value stored under key `Hello`
110
+ puts rocksdb["Hello"]
111
+ # => World
75
112
  ```
76
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
+
215
+ require "rocksdb"
216
+
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"
360
+
361
+ batch = RocksDB::Batch.new
362
+
363
+ batch.delete("test:batch1")
364
+ batch.put("test:batch2", "b")
365
+
366
+ rocksdb.write(batch)
367
+
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"
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
395
+ iterator.seek_to_first
396
+
397
+ while iterator.valid?
398
+ puts "#{iterator.value} = #{iterator.key}"
399
+ iterator.next
400
+ end
401
+
402
+ iterator.close
403
+ ```
404
+
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:
424
+
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`
428
+
429
+ Also, there some things that are now deprecated and will be removed in future versions:
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?`
437
+
77
438
  ## Contributing
78
439
 
79
440
  1. Fork it