The rocksdb is a persistent in-process key-value store.
Read more about it here: http://rocksdb.org/
This gem contains Ruby bindings so that you can use it from your Ruby process.
Add this line to your application's Gemfile:
gem 'rocksdb-ruby'And then execute:
$ bundleOr install it yourself as:
$ gem install rocksdb-rubyrocksdb-ruby is tested against Ruby 2.4, 2.5 and 2.6 on Linux and macOS platforms. However, it might work on other platforms.
rocksdb-ruby contains librocksdb 8.1.1.
JRuby, TruffleRuby and Rubinius are not supported at the moment.
First, you need to open database. Use open method and pass path to database
root as first argument. By default, it will create path if missing.
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file1"You can pass RocksDB options as second argument:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file2", compression: "kNoCompression"Or you can pass raw Option String:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file2", "compression=kNoCompression"Read more about Option Sting: https://github.com/facebook/rocksdb/wiki/Option-String-and-Option-Map#option-string
You can read and write keys using put and get methods:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file3"
# Store string `World` under key `Hello`
rocksdb.put "Hello", "World"
# Read a value stored under key `Hello`
puts rocksdb.get "Hello"
# => WorldYou can also use Hash-like methods [] and []=
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file4"
# Store string `World` under key `Hello`
rocksdb["Hello"] = "World"
# Read a value stored under key `Hello`
puts rocksdb["Hello"]
# => WorldIf key does not exists, RocksDB will return nil:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file5"
# Try to read a key, that does not exists
result = rocksdb.get "Missing Key"
if !result
puts "Key not found!"
end
# => Key not foundIf you want to get multiple keys at the same time, you can use get with multiple arguments:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file6"
rocksdb.put "First Key", "First Value"
rocksdb.put "Second Key", "Second Value"
rocksdb.put "Third Key", "Third Value"
# If key does not exists, you'll get nil
values = rocksdb.get "Second Key", "Imaginary Key", "Third Key"
puts values
# => ["Second Value", nil, "Third Value"]You can check, if key exists:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file7"
rocksdb.put "Real Key", "Real Value"
rocksdb.exists? "Real Key"
# => true
rocksdb.exists? "Imaginary Key"
# => falseexists? method returns result of KeyMayExist.
If you need more infomation about KeyMayExist, see rockdb source comments.
And you can delete keys, when not needed:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file8"
rocksdb.put "Delete Me", "Memory"
rocksdb.exists? "Delete Me"
# => true
rocksdb.delete "Delete Me"
rocksdb.exists? "Delete Me"
# => false
rocksdb.get "Delete Me"
# => nilYou can open RocksDB only for reading:
require "rocksdb"
# Open only for reading
rocksdb = RocksDB.open_readonly "/tmp/file9"
puts rocksdb.writable?
# => false
rocksdb.put "First Key", "First Value"
# => RocksDB::ReadOnly (database is read-only)You can enumerate over all values using each method. Note how values are sorted lexicographically by their keys:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file10"
rocksdb.put "One", "1"
rocksdb.put "Two", "2"
rocksdb.put "Three", "3"
rocksdb.each do |value|
puts value
end
# => 1
# => 3
# => 2Additionally, you can enumerate in reverse order with reverse_each:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file11"
rocksdb.put "One", "1"
rocksdb.put "Two", "2"
rocksdb.put "Three", "3"
rocksdb.reverse_each do |value|
puts value
end
# => 2
# => 3
# => 1You can enumerate over keys with each_key or in reverse order with reverse_each_key:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file12"
rocksdb.put "One", "1"
rocksdb.put "Two", "2"
rocksdb.put "Three", "3"
rocksdb.each_key do |key|
puts key
end
# => One
# => Three
# => Two
rocksdb.reverse_each_key do |key|
puts key
end
# => Two
# => Three
# => OneYou can enumerate over both keys and values with each_pair and in reverse order with reverse_each_pair:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file13"
rocksdb.put "One", "1"
rocksdb.put "Two", "2"
rocksdb.put "Three", "3"
rocksdb.each_pair do |key, value|
puts "#{key} = #{value}"
end
# => One = 1
# => Three = 3
# => Two = 2Additionally, you can enumerate over keys that start with a specific prefix with each_prefix:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file14"
rocksdb.put "my:1", "1"
rocksdb.put "my:2", "2"
rocksdb.put "your:3", "3"
rocksdb.each_prefix("my") do |key, value|
puts "#{key} = #{value}"
end
# => my:1 = 1
# => my:2 = 2Or you can scan over the ranges of keys with each_range. Note, range is [start, limit]:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file15"
10.times do |count|
rocksdb.put "key:#{count}", "#{count}"
end
rocksdb.each_range("key:5", "key:7") do |key, value|
puts "#{key} = #{value}"
end
# => key:5 = 5
# => key:6 = 6
# => key:7 = 7You can use RocksDB::Batch to atomically insert big chunks of data.
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file16"
batch = RocksDB::Batch.new
batch.delete("test:batch1")
batch.put("test:batch2", "b")
rocksdb.write(batch)
rocksdb.each_pair do |key, value|
puts "#{key} = #{value}"
end
# => test:batch2 = bRead more about RocksDB batches: https://github.com/facebook/rocksdb/wiki/Basic-Operations#atomic-updates
You can get RocksDB Iterator with to_iterator method to iterate over your data:
require "rocksdb"
# Open for reads and writes
rocksdb = RocksDB.open "/tmp/file16"
10.times do |count|
rocksdb.put "key:#{count}", "#{count}"
end
# Get Iterator
iterator = rocksdb.to_iterator
# Seek to some position. You can also use seek("key") to
iterator.seek_to_first
while iterator.valid?
puts "#{iterator.value} = #{iterator.key}"
iterator.next
end
iterator.closeSupported methods:
seek(key)seeks to closest key to given prefix at beginningseek_to_firstseeks to the first keyseek_to_lastseeks to the last keynextseeks to the next keypreviousseeks to the previous keyvalid?returns true if iterator can be iteratedclosecloses iteratorkeyreturns current keyvaluereturns current value
Methods supported by rocksdb 4.11 and later:
seek_for_previous(key)seeks to closest key to given prefix at end
When upgrading from 0.2 version, please note the following breaking changes:
multi_getwill returnnilinstead of empty stringRocksDB::DB.get_instanceis removed. Implement your own DB instance cache if neededeach_methods now returnsEnumeratorinstead ofRocksDB::Iterator
Also, there some things that are now deprecated and will be removed in future versions:
RocksDB::DBErrorwas deprecated and replaced withRocksDB::Error. Specific errors now have their own exception class:ReadOnly,DatabaseClosed,IteratorClosed,StatusErroris_open?was replaced withopen?is_readonly?was replaced withwritable?multi_getwas replaced withget_manynew_iteratorwas replaced withto_iteratorIterator#validwas replaced withIterator#valid?
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request