rocksdb-ruby 0.2.2 → 1.0.2

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: ab9bf6ef229b188fe7cf7ea87cb394febcc0450b
4
- data.tar.gz: 91d46e1f0540989f9bc6e51626d52e420a8d3ce1
2
+ SHA256:
3
+ metadata.gz: c1041bd77d389b6fe4d41acd47769b45b9d6f1fd545029dea025b796911d2426
4
+ data.tar.gz: f8f47e24c595bb65ef2ac74de8d21149a06045fbd9a5aca6b7bb2184e4358c26
5
5
  SHA512:
6
- metadata.gz: 40a526d28f4732f873ab11569fdd809bfebe381d4ab95d52db79dae7b356f30eaff00ae060a6f2dc81b4b29811beedfb237db998ed25c26f5acc2a72ce854965
7
- data.tar.gz: 9cc68467433768b8d861f39b37309112fde862b4b4bac322f2ee6daf60abec7e55af66a3d21bd0522565010202b2c05eca1daa192ed523e797b47623768cfc88
6
+ metadata.gz: 01dbe3df2ed1abe2cb8a9d6ad8793c65d75f92a8ae3f5a536e367c580ec081d3924d1ef4a0296227936614b5f280aad0e9638a72e0bdb28817cf1d5fce0400d5
7
+ data.tar.gz: 0cd0230be5cec78878496f499ef2887f237b7473a1a9d84a73b0fef785391ce2033653b65c76837346aa14a1b257fce46581553d1b4a427356d02d28da9eb816
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
@@ -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/.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
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,414 @@ 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
+
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
+
36
116
  ```ruby
37
- require "rocksdb"
38
117
 
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)
118
+ require "rocksdb"
46
119
 
47
- # Atomic Updates
48
- batch = RocksDB::Batch.new
49
- batch.delete("test:batch1")
50
- batch.put("test:batch2", "b")
51
- rocksdb.write(batch)
120
+ # Open for reads and writes
121
+ rocksdb = RocksDB.open "/tmp/file5"
52
122
 
53
- # Iteration
54
- iterator = rocksdb.new_iterator
123
+ # Try to read a key, that does not exists
124
+ result = rocksdb.get "Missing Key"
55
125
 
56
- iterator.seek_to_first
57
- while(iterator.valid)
58
- iterator.value
59
- iterator.key
60
- iterator.next
61
- end
62
- iterator.close
126
+ if !result
127
+ puts "Key not found!"
128
+ end
63
129
 
64
- # Block
65
- rocksdb.each do |data|
66
- puts data
67
- end
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
+ `exists?` method returns result of KeyMayExist.
172
+
173
+ If you need more infomation about KeyMayExist, see [rockdb source comments](https://github.com/facebook/rocksdb/blob/689b13e6396011317db4f04a88e72323aead32bd/include/rocksdb/db.h#L646-L662).
68
174
 
69
- # Hash access
70
- rocksdb['key'] = data
71
- puts rocksdb['key']
175
+ And you can delete keys, when not needed:
72
176
 
177
+ ```ruby
178
+
179
+ require "rocksdb"
180
+
181
+ # Open for reads and writes
182
+ rocksdb = RocksDB.open "/tmp/file8"
73
183
 
74
- rocksdb.close
184
+ rocksdb.put "Delete Me", "Memory"
185
+ rocksdb.exists? "Delete Me"
186
+ # => true
187
+ rocksdb.delete "Delete Me"
188
+ rocksdb.exists? "Delete Me"
189
+ # => false
190
+
191
+ rocksdb.get "Delete Me"
192
+ # => nil
75
193
  ```
76
194
 
195
+ You can open RocksDB only for reading:
196
+
197
+ ```ruby
198
+
199
+ require "rocksdb"
200
+
201
+ # Open only for reading
202
+ rocksdb = RocksDB.open_readonly "/tmp/file9"
203
+
204
+ puts rocksdb.writable?
205
+ # => false
206
+
207
+ rocksdb.put "First Key", "First Value"
208
+
209
+ # => RocksDB::ReadOnly (database is read-only)
210
+ ```
211
+
212
+
213
+ ### Enumerable
214
+
215
+ You can enumerate over all values using `each` method. Note how values are sorted lexicographically by their keys:
216
+
217
+ ```ruby
218
+
219
+ require "rocksdb"
220
+
221
+ # Open for reads and writes
222
+ rocksdb = RocksDB.open "/tmp/file10"
223
+
224
+ rocksdb.put "One", "1"
225
+ rocksdb.put "Two", "2"
226
+ rocksdb.put "Three", "3"
227
+
228
+ rocksdb.each do |value|
229
+ puts value
230
+ end
231
+
232
+ # => 1
233
+ # => 3
234
+ # => 2
235
+ ```
236
+
237
+ Additionally, you can enumerate in reverse order with `reverse_each`:
238
+
239
+ ```ruby
240
+
241
+ require "rocksdb"
242
+
243
+ # Open for reads and writes
244
+ rocksdb = RocksDB.open "/tmp/file11"
245
+
246
+ rocksdb.put "One", "1"
247
+ rocksdb.put "Two", "2"
248
+ rocksdb.put "Three", "3"
249
+
250
+ rocksdb.reverse_each do |value|
251
+ puts value
252
+ end
253
+
254
+ # => 2
255
+ # => 3
256
+ # => 1
257
+ ```
258
+
259
+ You can enumerate over keys with `each_key` or in reverse order with `reverse_each_key`:
260
+
261
+ ```ruby
262
+
263
+ require "rocksdb"
264
+
265
+ # Open for reads and writes
266
+ rocksdb = RocksDB.open "/tmp/file12"
267
+
268
+ rocksdb.put "One", "1"
269
+ rocksdb.put "Two", "2"
270
+ rocksdb.put "Three", "3"
271
+
272
+ rocksdb.each_key do |key|
273
+ puts key
274
+ end
275
+
276
+ # => One
277
+ # => Three
278
+ # => Two
279
+
280
+ rocksdb.reverse_each_key do |key|
281
+ puts key
282
+ end
283
+
284
+ # => Two
285
+ # => Three
286
+ # => One
287
+ ```
288
+
289
+ You can enumerate over both keys and values with `each_pair` and in reverse order with `reverse_each_pair`:
290
+
291
+ ```ruby
292
+
293
+ require "rocksdb"
294
+
295
+ # Open for reads and writes
296
+ rocksdb = RocksDB.open "/tmp/file13"
297
+
298
+ rocksdb.put "One", "1"
299
+ rocksdb.put "Two", "2"
300
+ rocksdb.put "Three", "3"
301
+
302
+ rocksdb.each_pair do |key, value|
303
+ puts "#{key} = #{value}"
304
+ end
305
+
306
+ # => One = 1
307
+ # => Three = 3
308
+ # => Two = 2
309
+ ```
310
+
311
+ Additionally, you can enumerate over keys that start with a specific prefix with `each_prefix`:
312
+
313
+ ```ruby
314
+
315
+ require "rocksdb"
316
+
317
+ # Open for reads and writes
318
+ rocksdb = RocksDB.open "/tmp/file14"
319
+
320
+ rocksdb.put "my:1", "1"
321
+ rocksdb.put "my:2", "2"
322
+ rocksdb.put "your:3", "3"
323
+
324
+ rocksdb.each_prefix("my") do |key, value|
325
+ puts "#{key} = #{value}"
326
+ end
327
+
328
+ # => my:1 = 1
329
+ # => my:2 = 2
330
+ ```
331
+
332
+ Or you can scan over the ranges of keys with `each_range`. Note, range is `[start, limit]`:
333
+
334
+ ```ruby
335
+
336
+ require "rocksdb"
337
+
338
+ # Open for reads and writes
339
+ rocksdb = RocksDB.open "/tmp/file15"
340
+
341
+ 10.times do |count|
342
+ rocksdb.put "key:#{count}", "#{count}"
343
+ end
344
+
345
+ rocksdb.each_range("key:5", "key:7") do |key, value|
346
+ puts "#{key} = #{value}"
347
+ end
348
+
349
+ # => key:5 = 5
350
+ # => key:6 = 6
351
+ # => key:7 = 7
352
+ ```
353
+
354
+ ### Atomic Batches
355
+
356
+ You can use `RocksDB::Batch` to atomically insert big chunks of data.
357
+
358
+ ```ruby
359
+
360
+ require "rocksdb"
361
+
362
+ # Open for reads and writes
363
+ rocksdb = RocksDB.open "/tmp/file16"
364
+
365
+ batch = RocksDB::Batch.new
366
+
367
+ batch.delete("test:batch1")
368
+ batch.put("test:batch2", "b")
369
+
370
+ rocksdb.write(batch)
371
+
372
+ rocksdb.each_pair do |key, value|
373
+ puts "#{key} = #{value}"
374
+ end
375
+
376
+ # => test:batch2 = b
377
+ ```
378
+
379
+ Read more about RocksDB batches: https://github.com/facebook/rocksdb/wiki/Basic-Operations#atomic-updates
380
+
381
+ # Iterator
382
+
383
+ You can get RocksDB Iterator with `to_iterator` method to iterate over your data:
384
+
385
+ ```ruby
386
+
387
+ require "rocksdb"
388
+
389
+ # Open for reads and writes
390
+ rocksdb = RocksDB.open "/tmp/file16"
391
+
392
+ 10.times do |count|
393
+ rocksdb.put "key:#{count}", "#{count}"
394
+ end
395
+
396
+ # Get Iterator
397
+ iterator = rocksdb.to_iterator
398
+ # Seek to some position. You can also use seek("key") to
399
+ iterator.seek_to_first
400
+
401
+ while iterator.valid?
402
+ puts "#{iterator.value} = #{iterator.key}"
403
+ iterator.next
404
+ end
405
+
406
+ iterator.close
407
+ ```
408
+
409
+ Supported methods:
410
+
411
+ * `seek(key)` seeks to closest key to given prefix at beginning
412
+ * `seek_to_first` seeks to the first key
413
+ * `seek_to_last` seeks to the last key
414
+ * `next` seeks to the next key
415
+ * `previous` seeks to the previous key
416
+ * `valid?` returns true if iterator can be iterated
417
+ * `close` closes iterator
418
+ * `key` returns current key
419
+ * `value` returns current value
420
+
421
+ Methods supported by rocksdb 4.11 and later:
422
+
423
+ * `seek_for_previous(key)`seeks to closest key to given prefix at end
424
+
425
+ ## Upgrade
426
+
427
+ When upgrading from `0.2` version, please note the following breaking changes:
428
+
429
+ * `multi_get` will return `nil` instead of empty string
430
+ * `RocksDB::DB.get_instance` is removed. Implement your own DB instance cache if needed
431
+ * `each_` methods now returns `Enumerator` instead of `RocksDB::Iterator`
432
+
433
+ Also, there some things that are now deprecated and will be removed in future versions:
434
+
435
+ * `RocksDB::DBError` was deprecated and replaced with `RocksDB::Error`. Specific errors now have their own exception class: `ReadOnly`, `DatabaseClosed`, `IteratorClosed`, `StatusError`
436
+ * `is_open?` was replaced with `open?`
437
+ * `is_readonly?` was replaced with `writable?`
438
+ * `multi_get` was replaced with `get_many`
439
+ * `new_iterator` was replaced with `to_iterator`
440
+ * `Iterator#valid` was replaced with `Iterator#valid?`
441
+
77
442
  ## Contributing
78
443
 
79
444
  1. Fork it