rocksdb-ruby 0.2.0 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,25 +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"
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
18
29
 
19
- batch = RocksDB::Batch.new
20
- batch.delete("test:batch1")
21
- batch.put("test:batch2", "b")
22
- expect{@rocksdb2.write(batch)}.to raise_error(RuntimeError)
30
+ after do
31
+ @rocksdb.close
32
+ end
23
33
  end
24
34
 
25
- after do
26
- @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
27
56
  end
28
57
  end
data/spec/db_spec.rb CHANGED
@@ -1,155 +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.get("test:read")).to eq "1"
13
- end
13
+ context "close" do
14
+ it 'closes database' do
15
+ @rocksdb.close
16
+ expect(@rocksdb.open?).to eq false
17
+ end
14
18
 
15
- it 'should put data' do
16
- expect(@rocksdb.put("test:put", "2")).to be true
17
- expect(@rocksdb.get("test:put")).to eq "2"
18
- 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
19
24
 
20
- it 'should delete data' do
21
- @rocksdb.put("test:delete", "3")
22
- expect(@rocksdb.get("test:delete")).to eq "3"
25
+ it 'raises exception on closed database' do
26
+ @rocksdb.close
23
27
 
24
- expect(@rocksdb.delete("test:delete")).to be true
25
- 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
26
33
  end
27
34
 
28
- it 'should get multi data' do
29
- @rocksdb.put("test:multi1", "a")
30
- @rocksdb.put("test:multi2", "b")
31
- @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
32
40
 
33
- 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
34
51
  end
35
52
 
36
- it 'should put data atomic update' do
37
- @rocksdb.put("test:batch1", "a")
38
- @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
39
59
 
40
- expect(@rocksdb.get("test:batch1")).to eq "a"
41
- 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
42
64
 
43
- batch = RocksDB::Batch.new
44
- batch.delete("test:batch1")
45
- batch.put("test:batch2", "b")
46
- @rocksdb.write(batch)
65
+ it 'should return nil if key not found' do
66
+ @rocksdb.delete("test:multi2")
47
67
 
48
- expect(@rocksdb.get("test:batch1")).to be_nil
49
- 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
50
71
  end
51
72
 
52
- it 'should use multiple db' do
53
- @rocksdb2 = RocksDB::DB.new "/tmp/file2"
54
-
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
115
+
116
+ def to_str
117
+ @value.to_s
118
+ end
119
+ end
72
120
 
73
- array = []
74
- @rocksdb.each do |value|
75
- expect(value).not_to be_empty
76
- array << value
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
138
+
139
+ batch = RocksDB::Batch.new
140
+ batch.delete("test:batch1")
141
+ batch.put("test:batch2", "b")
142
+ @rocksdb.write(batch)
87
143
 
88
- @rocksdb.each_index do |key|
89
- expect(key).not_to be_empty
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
172
+
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
105
177
 
106
- expect(@rocksdb.includes?("test:exists?")).to be true
107
- expect(@rocksdb.includes?("test:noexists?")).to be false
178
+ it 'returns false when key deleted' do
179
+ @rocksdb.put "test:deleted_key", "deleted_value"
180
+ @rocksdb.delete "test:deleted_key"
108
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}
229
+ @rocksdb2 = RocksDB.open_readonly(temp_db_path)
230
+ expect(@rocksdb2.writable?).to eq false
128
231
  expect(@rocksdb2.get("test:put")).to eq "1"
129
232
 
130
233
  @rocksdb.close
131
- @rocksdb = RocksDB::DB.new "/tmp/file"
234
+
235
+ expect(@rocksdb.open?).to eq false
236
+
237
+ @rocksdb = RocksDB.open(temp_db_path)
238
+ expect(@rocksdb.writable?).to eq true
239
+ expect(@rocksdb.open?).to eq true
132
240
  expect(@rocksdb.put("test:put", "2")).to be true
133
-
134
- @rocksdb3 = RocksDB::DB.new "/tmp/file", {:readonly => true}
241
+
242
+ @rocksdb3 = RocksDB.open_readonly(temp_db_path)
243
+ expect(@rocksdb3.writable?).to eq false
244
+ expect(@rocksdb3.open?).to eq true
135
245
  expect(@rocksdb3.get("test:put")).to eq "2"
136
-
137
- end
138
-
139
- it 'singleton' do
140
- @rocksdb2 = RocksDB::DB.get_instance("/tmp/file")
141
- @rocksdb3 = RocksDB::DB.get_instance("/tmp/file")
142
- expect(@rocksdb).to eq (@rocksdb3)
143
- expect(@rocksdb2).to eq (@rocksdb3)
144
-
145
- @rocksdb4 = RocksDB::DB.get_instance("/tmp/file", {:readonly => true})
146
- expect(@rocksdb2).not_to eq (@rocksdb4)
147
246
 
148
247
  @rocksdb2.close
149
- expect{@rocksdb2.get("test:put")}.to raise_error(RuntimeError)
150
- expect{@rocksdb3.get("test:put")}.to raise_error(RuntimeError)
248
+ @rocksdb3.close
151
249
  end
152
-
250
+
153
251
  context 'compact' do
154
252
  it 'works with no parameters' do
155
253
  expect(@rocksdb.compact).to eq(true)
@@ -172,4 +270,3 @@ describe RocksDB do
172
270
  @rocksdb.close
173
271
  end
174
272
  end
175
-
@@ -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