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.
@@ -4,26 +4,54 @@ require "rocksdb"
4
4
 
5
5
  describe RocksDB do
6
6
  before do
7
- @rocksdb = RocksDB::DB.new "/tmp/file2"
8
- @rocksdb.put("test:multi_db", "1")
7
+ @rocksdb = RocksDB.open temp_db_path
8
+ @rocksdb.put("test", "value")
9
9
  @rocksdb.close
10
-
11
- @rocksdb2 = RocksDB::DB.new("/tmp/file2", {:readonly => true})
12
10
  end
13
11
 
14
- it 'should get data' do
15
- expect{@rocksdb2.put("test:multi_db", "10")}.to raise_error(RuntimeError)
16
- expect{@rocksdb2.delete("test:multi_db")}.to raise_error(RuntimeError)
17
- expect(@rocksdb2.get("test:multi_db")).to eq "1"
18
- expect(@rocksdb2.is_readonly?).to eq true
19
-
20
- batch = RocksDB::Batch.new
21
- batch.delete("test:batch1")
22
- batch.put("test:batch2", "b")
23
- expect{@rocksdb2.write(batch)}.to raise_error(RuntimeError)
12
+ context "when writable" do
13
+ before do
14
+ @rocksdb = RocksDB.open temp_db_path
15
+ end
16
+
17
+ it 'writable? is true' do
18
+ expect(@rocksdb.writable?).to eq true
19
+ end
20
+
21
+ it 'can write' do
22
+ expect{@rocksdb.put("newtest", "value")}
23
+ .not_to raise_error
24
+ end
25
+
26
+ it 'can read' do
27
+ expect(@rocksdb.get("test")).to eq "value"
28
+ end
29
+
30
+ after do
31
+ @rocksdb.close
32
+ end
24
33
  end
25
34
 
26
- after do
27
- @rocksdb2.close
35
+ context "when not writable" do
36
+ before do
37
+ @rocksdb = RocksDB.open_readonly temp_db_path
38
+ end
39
+
40
+ it 'writable? is false' do
41
+ expect(@rocksdb.writable?).to eq false
42
+ end
43
+
44
+ it "can't write" do
45
+ expect{@rocksdb.put("newtest", "value")}
46
+ .to raise_error(RocksDB::ReadOnly)
47
+ end
48
+
49
+ it 'can read' do
50
+ expect(@rocksdb.get("test")).to eq "value"
51
+ end
52
+
53
+ after do
54
+ @rocksdb.close
55
+ end
28
56
  end
29
57
  end
data/spec/db_spec.rb CHANGED
@@ -1,176 +1,253 @@
1
1
  # -*- coding: utf-8 -*-
2
2
  require 'spec_helper'
3
3
  require "rocksdb"
4
+ require 'fileutils'
4
5
 
5
6
  describe RocksDB do
7
+ warn "RocksDB library version: #{RocksDB::library_version}" rescue nil
8
+
6
9
  before do
7
- @rocksdb = RocksDB::DB.new("/tmp/file")
10
+ @rocksdb = RocksDB.open(temp_db_path)
8
11
  end
9
12
 
10
- it 'should get data' do
11
- @rocksdb.put("test:read", "1")
12
- expect(@rocksdb.is_readonly?).to eq false
13
- expect(@rocksdb.get("test:read")).to eq "1"
14
- end
13
+ context "close" do
14
+ it 'closes database' do
15
+ @rocksdb.close
16
+ expect(@rocksdb.open?).to eq false
17
+ end
15
18
 
16
- it 'should put data' do
17
- expect(@rocksdb.put("test:put", "2")).to be true
18
- expect(@rocksdb.get("test:put")).to eq "2"
19
- end
19
+ it 'not fails to close database that is already closes' do
20
+ @rocksdb.close
21
+ @rocksdb.close
22
+ expect(@rocksdb.open?).to eq false
23
+ end
20
24
 
21
- it 'should delete data' do
22
- @rocksdb.put("test:delete", "3")
23
- expect(@rocksdb.get("test:delete")).to eq "3"
25
+ it 'raises exception on closed database' do
26
+ @rocksdb.close
24
27
 
25
- expect(@rocksdb.delete("test:delete")).to be true
26
- expect(@rocksdb.get("test:delete")).to be_nil
28
+ expect{ @rocksdb.get "test" }
29
+ .to raise_error(RocksDB::DatabaseClosed)
30
+ expect{ @rocksdb.put "test", "value" }
31
+ .to raise_error(RocksDB::DatabaseClosed)
32
+ end
27
33
  end
28
34
 
29
- it 'should get multi data' do
30
- @rocksdb.put("test:multi1", "a")
31
- @rocksdb.put("test:multi2", "b")
32
- @rocksdb.put("test:multi3", "c")
35
+ context "get_one" do
36
+ it 'should get data' do
37
+ @rocksdb.put("test:read", "1")
38
+ expect(@rocksdb.get_one("test:read")).to eq "1"
39
+ end
33
40
 
34
- expect(@rocksdb.multi_get(["test:multi1", "test:multi2", "test:multi3"])).to eq ["a", "b", "c"]
41
+ it 'should get with []' do
42
+ @rocksdb.delete("test:hash")
43
+ expect(@rocksdb["test:hash"]).to be_nil
44
+ @rocksdb.put("test:hash", "42")
45
+ expect(@rocksdb["test:hash"]).to eq "42"
46
+ end
47
+
48
+ it 'should return nil if not found' do
49
+ expect(@rocksdb.get_one("must_not_be_found")).to be_nil
50
+ end
35
51
  end
36
52
 
37
- it 'should put data atomic update' do
38
- @rocksdb.put("test:batch1", "a")
39
- @rocksdb.delete("test:batch2")
53
+ context "get_many" do
54
+ before do
55
+ @rocksdb.put("test:multi1", "a")
56
+ @rocksdb.put("test:multi2", "b")
57
+ @rocksdb.put("test:multi3", "c")
58
+ end
40
59
 
41
- expect(@rocksdb.get("test:batch1")).to eq "a"
42
- expect(@rocksdb.get("test:batch")).to be_nil
60
+ it 'should get all values' do
61
+ expect(@rocksdb.get_many(["test:multi1", "test:multi2", "test:multi3"]))
62
+ .to eq ["a", "b", "c"]
63
+ end
43
64
 
44
- batch = RocksDB::Batch.new
45
- batch.delete("test:batch1")
46
- batch.put("test:batch2", "b")
47
- @rocksdb.write(batch)
65
+ it 'should return nil if key not found' do
66
+ @rocksdb.delete("test:multi2")
48
67
 
49
- expect(@rocksdb.get("test:batch1")).to be_nil
50
- expect(@rocksdb.get("test:batch2")).to eq "b"
68
+ expect(@rocksdb.get_many(["test:multi1", "test:multi2", "test:multi3"]))
69
+ .to eq ["a", nil, "c"]
70
+ end
51
71
  end
52
72
 
53
- it 'should use multiple db' do
54
- @rocksdb2 = RocksDB::DB.new("/tmp/file2")
55
- @rocksdb.put("test:multi_db", "1")
56
- @rocksdb2.put("test:multi_db", "2")
57
-
58
- expect(@rocksdb.get("test:multi_db")).to eq "1"
59
- expect(@rocksdb2.get("test:multi_db")).to eq "2"
60
- @rocksdb2.close
61
- end
73
+ context "get" do
74
+ before do
75
+ @rocksdb.put("test:multi1", "a")
76
+ @rocksdb.put("test:multi2", "b")
77
+ @rocksdb.put("test:multi3", "c")
78
+ end
79
+
80
+ it 'should get one, when one argument' do
81
+ expect(@rocksdb.get("test:multi2"))
82
+ .to eq "b"
83
+ end
62
84
 
63
- it 'should use japanese charactor' do
64
- @rocksdb.put("test:japanese", "あいうえお")
85
+ it 'should get many, when two or more arguments' do
86
+ expect(@rocksdb.get("test:multi1", "test:multi2", "test:multi3"))
87
+ .to eq ["a", "b", "c"]
88
+ end
65
89
 
66
- expect(@rocksdb.get("test:japanese")).to eq "あいうえお"
67
- expect(@rocksdb.multi_get(["test:japanese"])).to eq ["あいうえお"]
90
+ it 'should get many, when array given' do
91
+ expect(@rocksdb.get(["test:multi1", "test:multi2", "test:multi3"]))
92
+ .to eq ["a", "b", "c"]
93
+ end
68
94
  end
69
95
 
70
- it 'should use each' do
71
- iter = @rocksdb.each
96
+ context "put" do
97
+ it 'should put data' do
98
+ expect(@rocksdb.put("test:put", "2")).to be true
99
+ expect(@rocksdb.get("test:put")).to eq "2"
100
+ end
101
+
102
+ it 'should overwrite data with put' do
103
+ expect(@rocksdb.put("test:put", "2")).to be true
104
+ expect(@rocksdb.get("test:put")).to eq "2"
105
+
106
+ expect(@rocksdb.put("test:put", "3")).to be true
107
+ expect(@rocksdb.get("test:put")).to eq "3"
108
+ end
109
+
110
+ it 'should put any data that can behave like string' do
111
+ class CastableTest
112
+ def initialize(value)
113
+ @value = value
114
+ end
72
115
 
73
- array = []
74
- @rocksdb.each do |value|
75
- expect(value).not_to be_empty
76
- array << value
116
+ def to_str
117
+ @value.to_s
118
+ end
119
+ end
120
+
121
+ castable_key = CastableTest.new(42)
122
+ castable_value = CastableTest.new([1984])
123
+
124
+ expect(@rocksdb.put(castable_key, castable_value)).to be true
125
+ expect(@rocksdb.get("42")).to eq "[1984]"
77
126
  end
78
127
 
79
- rev_array = []
80
- @rocksdb.reverse_each do |value|
81
- expect(value).not_to be_empty
82
- rev_array << value
128
+ it "should gracefully fail on non-string objects" do
129
+ expect{ @rocksdb.put(42, true) }.to raise_error(TypeError)
83
130
  end
84
-
85
131
 
86
- expect(array).to eq rev_array.reverse
132
+ it 'should put data atomic update' do
133
+ @rocksdb.put("test:batch1", "a")
134
+ @rocksdb.delete("test:batch2")
135
+
136
+ expect(@rocksdb.get("test:batch1")).to eq "a"
137
+ expect(@rocksdb.get("test:batch")).to be_nil
87
138
 
88
- @rocksdb.each_index do |key|
89
- expect(key).not_to be_empty
139
+ batch = RocksDB::Batch.new
140
+ batch.delete("test:batch1")
141
+ batch.put("test:batch2", "b")
142
+ @rocksdb.write(batch)
143
+
144
+ expect(@rocksdb.get("test:batch1")).to be_nil
145
+ expect(@rocksdb.get("test:batch2")).to eq "b"
90
146
  end
91
147
 
92
- @rocksdb.each_with_index do |key, value|
93
- expect(key).not_to be_empty
94
- expect(value).not_to be_empty
148
+ it 'should put and read multibyte data' do
149
+ @rocksdb.put("test:japanese", "あいうえお")
150
+ @rocksdb.put("test:russian", "Перепёлка")
151
+
152
+ expect(@rocksdb.get("test:japanese")).to eq "あいうえお"
153
+ expect(@rocksdb.get("test:japanese", "test:russian"))
154
+ .to eq ["あいうえお", "Перепёлка"]
95
155
  end
96
156
 
97
- iter.close
157
+ it 'should put with []=' do
158
+ @rocksdb.delete("test:hash")
159
+ expect(@rocksdb["test:hash"]).to be_nil
160
+ @rocksdb["test:hash"] = "a"
161
+ expect(@rocksdb.get("test:hash")).to eq "a"
162
+ end
98
163
  end
99
164
 
100
- it 'should exists?' do
101
- @rocksdb.put("test:exists?", "a")
102
- @rocksdb.delete("test:noexists?")
103
- expect(@rocksdb.exists?("test:exists?")).to be true
104
- expect(@rocksdb.exists?("test:noexists?")).to be false
165
+ context "exists?" do
166
+ it 'returns true when exists' do
167
+ @rocksdb.put "test:exists?", "a"
168
+
169
+ expect(@rocksdb.exists?("test:exists?")).to be true
170
+ expect(@rocksdb.includes?("test:exists?")).to be true
171
+ end
105
172
 
106
- expect(@rocksdb.includes?("test:exists?")).to be true
107
- expect(@rocksdb.includes?("test:noexists?")).to be false
173
+ it 'returns false when no exists' do
174
+ expect(@rocksdb.exists?("test:noexists?")).to be false
175
+ expect(@rocksdb.includes?("test:noexists?")).to be false
176
+ end
108
177
 
178
+ it 'returns false when key deleted' do
179
+ @rocksdb.put "test:deleted_key", "deleted_value"
180
+ @rocksdb.delete "test:deleted_key"
181
+
182
+ expect(@rocksdb.exists?("test:deleted_key")).to be false
183
+ expect(@rocksdb.includes?("test:deleted_key")).to be false
184
+ end
109
185
  end
110
186
 
111
- it 'hash' do
112
- @rocksdb.delete("test:hash")
113
- expect(@rocksdb["test:hash"]).to be_nil
114
- @rocksdb["test:hash"] = "a"
115
- expect(@rocksdb["test:hash"]).to eq "a"
187
+ context "delete" do
188
+ it 'should delete data' do
189
+ @rocksdb.put("test:delete", "3")
190
+ expect(@rocksdb.get("test:delete")).to eq "3"
191
+
192
+ expect(@rocksdb.delete("test:delete")).to be true
193
+ expect(@rocksdb.get("test:delete")).to be_nil
194
+ end
195
+
196
+ it 'should return true even if key does not exists' do
197
+ @rocksdb.delete("must_not_be_found_to_delete")
198
+ expect(@rocksdb.delete("must_not_be_found_to_delete")).to be true
199
+ end
200
+ end
116
201
 
202
+ it "should get property" do
203
+ @rocksdb.put("test:read", "1")
204
+ expect(@rocksdb.property("rocksdb.estimate-num-keys")).to eq("1")
205
+ end
206
+
207
+ it "should get library_version" do
208
+ expect(RocksDB.library_version).to match(/\d+\.\d+\.\d+/)
209
+ end
210
+
211
+ it 'should use multiple db' do
212
+ @rocksdb2 = RocksDB::DB.new("/tmp/file2")
213
+ @rocksdb.put("test:multi_db", "1")
214
+ @rocksdb2.put("test:multi_db", "2")
215
+
216
+ expect(@rocksdb.get("test:multi_db")).to eq "1"
217
+ expect(@rocksdb2.get("test:multi_db")).to eq "2"
218
+ @rocksdb2.close
117
219
  end
118
220
 
119
221
  it 'race condition test' do
120
222
  key = "test"
121
223
  value = "1"
122
224
 
123
- expect{RocksDB::DB.new("/tmp/file")}.to raise_error(RocksDB::DBError)
225
+ expect{RocksDB.open(temp_db_path)}.to raise_error(RocksDB::Error)
124
226
 
125
227
  expect(@rocksdb.put("test:put", "1")).to be true
126
228
 
127
- @rocksdb2 = RocksDB::DB.new("/tmp/file", {:readonly => true})
128
- expect(@rocksdb2.is_readonly?).to eq true
229
+ @rocksdb2 = RocksDB.open_readonly(temp_db_path)
230
+ expect(@rocksdb2.writable?).to eq false
129
231
  expect(@rocksdb2.get("test:put")).to eq "1"
130
232
 
131
233
  @rocksdb.close
132
234
 
133
- expect(@rocksdb.is_open?).to eq false
235
+ expect(@rocksdb.open?).to eq false
134
236
 
135
- @rocksdb = RocksDB::DB.new("/tmp/file")
136
- expect(@rocksdb.is_readonly?).to eq false
137
- expect(@rocksdb.is_open?).to eq true
237
+ @rocksdb = RocksDB.open(temp_db_path)
238
+ expect(@rocksdb.writable?).to eq true
239
+ expect(@rocksdb.open?).to eq true
138
240
  expect(@rocksdb.put("test:put", "2")).to be true
139
-
140
- @rocksdb3 = RocksDB::DB.new("/tmp/file", {:readonly => true})
141
- expect(@rocksdb3.is_readonly?).to eq true
142
- expect(@rocksdb3.is_open?).to eq true
241
+
242
+ @rocksdb3 = RocksDB.open_readonly(temp_db_path)
243
+ expect(@rocksdb3.writable?).to eq false
244
+ expect(@rocksdb3.open?).to eq true
143
245
  expect(@rocksdb3.get("test:put")).to eq "2"
144
246
 
145
247
  @rocksdb2.close
146
248
  @rocksdb3.close
147
-
148
249
  end
149
-
150
- it 'singleton' do
151
- @rocksdb2 = RocksDB::DB.get_instance("/tmp/file")
152
- expect(@rocksdb2.is_readonly?).to eq false
153
- expect(@rocksdb2.is_open?).to eq true
154
-
155
- @rocksdb3 = RocksDB::DB.get_instance("/tmp/file")
156
- expect(@rocksdb3.is_readonly?).to eq false
157
- expect(@rocksdb).to eq (@rocksdb3)
158
- expect(@rocksdb2).to eq (@rocksdb3)
159
-
160
- @rocksdb4 = RocksDB::DB.get_instance("/tmp/file", {:readonly => true})
161
- expect(@rocksdb2).not_to eq (@rocksdb4)
162
- expect(@rocksdb4.is_readonly?).to eq true
163
- expect(@rocksdb4.is_open?).to eq true
164
-
165
- @rocksdb2.close
166
- expect{@rocksdb2.get("test:put")}.to raise_error(RuntimeError)
167
- expect(@rocksdb2.is_open?).to eq false
168
- expect{@rocksdb3.get("test:put")}.to raise_error(RuntimeError)
169
- expect(@rocksdb3.is_open?).to eq false
170
250
 
171
- @rocksdb4.close
172
- end
173
-
174
251
  context 'compact' do
175
252
  it 'works with no parameters' do
176
253
  expect(@rocksdb.compact).to eq(true)
@@ -193,4 +270,3 @@ describe RocksDB do
193
270
  @rocksdb.close
194
271
  end
195
272
  end
196
-
@@ -2,38 +2,325 @@
2
2
  require 'spec_helper'
3
3
  require "RocksDB"
4
4
 
5
- describe RocksDB do
5
+ describe RocksDB::Iterator do
6
6
  before do
7
- @rocksdb = RocksDB::DB.new "/tmp/file"
7
+ @rocksdb = RocksDB.open temp_db_path
8
+
9
+ @rocksdb.put("test1:0001", "a")
10
+ @rocksdb.put("test1:0002", "b")
11
+ @rocksdb.put("test1:0003", "c")
12
+ @rocksdb.put("test1:0004", "d")
13
+ @rocksdb.put("test1:0005", "e")
14
+
15
+ @iterator = @rocksdb.to_iterator
16
+ end
17
+
18
+ context "valid" do
19
+ it 'should be valid at start' do
20
+ @iterator.seek_to_first
21
+
22
+ expect(@iterator).to be_valid
23
+ end
24
+
25
+ it 'should not be valid at end' do
26
+ @iterator.seek_to_last
27
+ @iterator.next
28
+
29
+ expect(@iterator).to_not be_valid
30
+ end
31
+
32
+ it 'should not be valid when closed' do
33
+ @iterator.close
34
+
35
+ expect(@iterator).to_not be_valid
36
+ end
37
+
38
+ it 'should not be valid when database closed' do
39
+ @rocksdb.close
40
+
41
+ expect(@iterator).to_not be_valid
42
+ end
43
+ end
44
+
45
+ context 'close' do
46
+ it 'closes iterator' do
47
+ @iterator.close
48
+ expect(@iterator).to_not be_valid
49
+ end
50
+
51
+ it 'raises exception on closed iterator' do
52
+ @iterator.close
53
+ expect{@iterator.seek_to_first}.to raise_error(RocksDB::IteratorClosed)
54
+ end
55
+
56
+ it 'raises exception on closed database' do
57
+ @rocksdb.close
58
+ expect{@iterator.seek_to_first}.to raise_error(RocksDB::DatabaseClosed)
59
+ end
60
+ end
61
+
62
+ context "enumerable" do
63
+ context "each" do
64
+ it 'iterates over all values' do
65
+ values = []
66
+
67
+ @rocksdb.each do |value|
68
+ values << value
69
+ end
70
+
71
+ expect(values).to eq ["a", "b", "c", "d", "e"]
72
+ end
73
+
74
+ it 'returns enumerable' do
75
+ expect(@rocksdb.each)
76
+ .to be_a(Enumerable)
77
+ end
78
+ end
79
+
80
+ context "reverse_each" do
81
+ it 'iterates over all values in reverse order' do
82
+ values = []
83
+
84
+ @rocksdb.reverse_each do |value|
85
+ values << value
86
+ end
87
+
88
+ expect(values).to eq ["e", "d", "c", "b", "a"]
89
+ end
90
+
91
+ it 'returns enumerable' do
92
+ expect(@rocksdb.reverse_each)
93
+ .to be_a(Enumerable)
94
+ end
95
+ end
96
+
97
+ context "each_key" do
98
+ it 'iterates over all keys' do
99
+ keys = []
100
+
101
+ @rocksdb.each_key do |key|
102
+ keys << key
103
+ end
104
+
105
+ expect(keys).to eq [
106
+ "test1:0001",
107
+ "test1:0002",
108
+ "test1:0003",
109
+ "test1:0004",
110
+ "test1:0005"
111
+ ]
112
+ end
113
+
114
+ it 'returns enumerable' do
115
+ expect(@rocksdb.each_key)
116
+ .to be_a(Enumerable)
117
+ end
118
+ end
119
+
120
+ context "reverse_each_key" do
121
+ it 'iterates over all keys in reverse order' do
122
+ keys = []
123
+
124
+ @rocksdb.reverse_each_key do |key|
125
+ keys << key
126
+ end
127
+
128
+ expect(keys).to eq [
129
+ "test1:0005",
130
+ "test1:0004",
131
+ "test1:0003",
132
+ "test1:0002",
133
+ "test1:0001"
134
+ ]
135
+ end
136
+
137
+ it 'returns enumerable' do
138
+ expect(@rocksdb.reverse_each_key)
139
+ .to be_a(Enumerable)
140
+ end
141
+ end
142
+
143
+ context "each_pair" do
144
+ it 'iterates over all values and keys' do
145
+ pairs = {}
146
+
147
+ @rocksdb.each_pair do |key, value|
148
+ pairs[key] = value
149
+ end
150
+
151
+ expect(pairs).to eq ({
152
+ "test1:0001"=>"a",
153
+ "test1:0002"=>"b",
154
+ "test1:0003"=>"c",
155
+ "test1:0004"=>"d",
156
+ "test1:0005"=>"e"
157
+ })
158
+ end
159
+
160
+ it 'returns enumerable' do
161
+ expect(@rocksdb.each_pair)
162
+ .to be_a(Enumerable)
163
+ end
164
+ end
165
+
166
+ context "reverse_each_pair" do
167
+ it 'iterates over all values and keys in reverse order' do
168
+ pairs = {}
169
+
170
+ @rocksdb.reverse_each_pair do |key, value|
171
+ pairs[key] = value
172
+ end
173
+
174
+ expect(pairs).to eq ({
175
+ "test1:0005"=>"e",
176
+ "test1:0004"=>"d",
177
+ "test1:0003"=>"c",
178
+ "test1:0002"=>"b",
179
+ "test1:0001"=>"a"
180
+ })
181
+ end
182
+
183
+ it 'returns enumerable' do
184
+ expect(@rocksdb.reverse_each_pair)
185
+ .to be_a(Enumerable)
186
+ end
187
+ end
188
+
189
+ context "each_prefix" do
190
+ it 'iterates over keys and values of given prefix' do
191
+ @rocksdb.put("test0:0000", "z")
192
+ @rocksdb.put("test2:0000", "u")
193
+ result = {}
194
+
195
+ @rocksdb.each_prefix("test1") do |key, value|
196
+ result[key] = value
197
+ end
198
+
199
+ expect(result).to eq({
200
+ "test1:0001" => "a",
201
+ "test1:0002" => "b",
202
+ "test1:0003" => "c",
203
+ "test1:0004" => "d",
204
+ "test1:0005" => "e",
205
+ })
206
+ end
207
+
208
+ it 'returns enumerable' do
209
+ expect(@rocksdb.each_prefix("test1"))
210
+ .to be_a(Enumerable)
211
+ end
212
+ end
213
+
214
+ context "each_range" do
215
+ it 'iterates over keys and values of given range' do
216
+ @rocksdb.put("test0:0001", "-1")
217
+ @rocksdb.put("test2:multi3", "f")
218
+
219
+ result = {}
220
+
221
+ @rocksdb.each_range("test1:0002", "test1:0004") do |key, value|
222
+ result[key] = value
223
+ end
224
+
225
+ expect(result).to eq({
226
+ "test1:0002" => "b",
227
+ "test1:0003" => "c",
228
+ "test1:0004" => "d"
229
+ })
230
+ end
231
+
232
+ it 'returns enumerable' do
233
+ expect(@rocksdb.each_range("test1:0002", "test1:0004"))
234
+ .to be_a(Enumerable)
235
+ end
236
+ end
237
+ end
238
+
239
+ it 'should seek to first' do
240
+ @iterator.seek_to_first
241
+
242
+ expect(@iterator.key).to eq "test1:0001"
243
+ expect(@iterator.value).to eq "a"
244
+ end
245
+
246
+ it 'should seek to last' do
247
+ @iterator.seek_to_last
248
+
249
+ expect(@iterator.key).to eq "test1:0005"
250
+ expect(@iterator.value).to eq "e"
251
+ end
252
+
253
+ context "seek" do
254
+ it 'should seek to record when record exists' do
255
+ @iterator.seek "test1:0003"
256
+
257
+ expect(@iterator.key).to eq "test1:0003"
258
+ expect(@iterator.value).to eq "c"
259
+ end
260
+
261
+ it 'should seek to first' do
262
+ @iterator.seek "alpha"
263
+
264
+ expect(@iterator).to be_valid
265
+ expect(@iterator.key).to eq "test1:0001"
266
+ expect(@iterator.value).to eq "a"
267
+ end
8
268
  end
9
269
 
10
- it 'should use iterator' do
11
- iterator = @rocksdb.new_iterator
270
+ context "seek_for_previous",
271
+ skip: !RocksDB::Iterator.instance_methods.include?(:seek_for_previous) do
12
272
 
13
- iterator.seek_to_first
14
-
15
- expect(iterator.valid).to be true
16
- while(iterator.valid)
17
- expect(iterator.value).not_to be_empty
18
- expect(iterator.key).not_to be_empty
19
- iterator.next
273
+ it 'should seek to record when target record exists' do
274
+ @iterator.seek_for_previous "test1:0004"
275
+
276
+ expect(@iterator.key).to eq "test1:0004"
277
+ expect(@iterator.value).to eq "d"
278
+ end
279
+
280
+ it 'should seek to closest record when target is not exists' do
281
+ @iterator.seek_for_previous "test2"
282
+
283
+ expect(@iterator.key).to eq "test1:0005"
284
+ expect(@iterator.value).to eq "e"
20
285
  end
21
- iterator.close
22
286
  end
23
287
 
24
- it 'should seek iterator' do
25
- iterator = @rocksdb.new_iterator
288
+ it 'should go forward' do
289
+ @iterator.seek_to_first
290
+ @iterator.next
291
+
292
+ expect(@iterator.key).to eq "test1:0002"
293
+ expect(@iterator.value).to eq "b"
294
+ end
26
295
 
27
- iterator.seek("test:put")
28
-
29
- iterator.valid
30
- expect(iterator.value).to eq "2"
31
- expect(iterator.key).to eq "test:put"
296
+ it 'should go back' do
297
+ @iterator.seek_to_last
298
+ @iterator.previous
299
+
300
+ expect(@iterator.key).to eq "test1:0004"
301
+ expect(@iterator.value).to eq "d"
302
+ end
303
+
304
+ it 'should iterate all the way to the end' do
305
+ result = {}
306
+ @iterator.seek_to_first
307
+
308
+ while @iterator.valid?
309
+ result[@iterator.key] = @iterator.value
310
+ @iterator.next
311
+ end
32
312
 
33
- iterator.close
313
+ expect(result).to eq ({
314
+ "test1:0001" => "a",
315
+ "test1:0002" => "b",
316
+ "test1:0003" => "c",
317
+ "test1:0004" => "d",
318
+ "test1:0005" => "e"
319
+ })
34
320
  end
35
321
 
36
322
  after do
323
+ @iterator.close
37
324
  @rocksdb.close
38
325
  end
39
326
  end