Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reverse_each method to db #12

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ sudo apt-get install libleveldb-dev libleveldb1v5 libsnappy1v5
dependencies:
leveldb:
github: "crystal-community/leveldb"
version: "~> 0.2.0"
version: "~> 0.3.0"
```

## Usage
Expand Down
2 changes: 1 addition & 1 deletion shard.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name: leveldb
version: 0.2.0
version: 0.3.0

authors:
- Sergey Potapov <[email protected]>
Expand Down
21 changes: 21 additions & 0 deletions spec/leveldb/db_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,27 @@ describe LevelDB do
end
end

describe "#reverse_each" do
it "iterates through all the keys in reverse" do
FileUtils.rm_r(TEST_DB) if Dir.exists?(TEST_DB)
db = LevelDB::DB.new(TEST_DB)

out = ""

db.put("k1", "v1")
db.put("k2", "v2")
db.put("k3", "v3")

db.reverse_each do |key, val|
out += "#{key}=#{val};"
end

out.should eq "k3=v3;k2=v2;k1=v1;"

db.close
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same:

it "..." do
  db = ...
rescue
  db.close
end

end
end

describe "#clear" do
it "removes all the keys" do
FileUtils.rm_r(TEST_DB) if Dir.exists?(TEST_DB)
Expand Down
6 changes: 6 additions & 0 deletions spec/leveldb/iterator_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ describe LevelDB::Iterator do
iterator.seek_to_last
iterator.key.should eq "k2"

iterator.prev
iterator.key.should eq "k1"

iterator.prev
iterator.valid?.should eq false

iterator.destroy
db.close
end
Expand Down
33 changes: 27 additions & 6 deletions src/leveldb/db.cr
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,15 @@ module LevelDB
end

def each : Void
iterator = Iterator.new(self)
iterator.seek_to_first
while iterator.valid?
yield(iterator.key, iterator.value)
iterator.next
iterate do |key, value|
yield(key, value)
end
end

def reverse_each : Void
iterate(true) do |key, value|
yield(key, value)
end
iterator.destroy
end

def clear
Expand Down Expand Up @@ -141,5 +143,24 @@ module LevelDB
raise(Error.new(message))
end
end

private def iterate(reversed : Bool = false) : Void
iterator = Iterator.new(self)
if reversed
iterator.seek_to_last
else
iterator.seek_to_first
end

while iterator.valid?
yield(iterator.key, iterator.value)
if reversed
iterator.prev
else
iterator.next
end
end
iterator.destroy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iterator should be destroyed in the rescue statement:

private def iterate(reversed : Bool = false) : Void
  iterator = Iterator.new(self)
  ...
rescue
  iterator.destroy
end

end
end
end
4 changes: 4 additions & 0 deletions src/leveldb/iterator.cr
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ module LevelDB
LibLevelDB.leveldb_iter_next(@iter_ptr)
end

def prev
LibLevelDB.leveldb_iter_prev(@iter_ptr)
end

def destroy
LibLevelDB.leveldb_iter_destroy(@iter_ptr)
end
Expand Down
1 change: 1 addition & 0 deletions src/leveldb/lib_leveldb.cr
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ lib LibLevelDB
fun leveldb_create_iterator(db : Void*, roptions : Void*) : Void*
fun leveldb_iter_destroy(iterator : Void*)
fun leveldb_iter_next(iterator : Void*)
fun leveldb_iter_prev(iterator : Void*)
fun leveldb_iter_key(iterator : Void*, klen : SizeT*) : UInt8*
fun leveldb_iter_value(iterator : Void*, vlen : SizeT*) : UInt8*
fun leveldb_iter_get_error(iterator : Void*, errptr : Void*)
Expand Down