rocksdb-ruby 0.2.0 → 1.0.1

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
- 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