This package provides bindings for KyotoCabinet key-value storage.
Pkg.add("KyotoCabinet")
using KyotoCabinet
To open database, use open
method:
db = open("db.kch", "r")
# db::Dict{Array{Uint8,1},Array{Uint8,1}}
close(db)
There is also bracketed version:
open(Db{K,V}(), "db.kch", "w+") do db
# db::Dict{K,V}
# do stuff...
end
Db
object implements basic collections and Dict
methods.
open(Db{String,String}(), "db.kch", "w+") do db
# Basic getindex, setindex! methods
db["a"] = "1"
println(db["a"])
# Dict methods also implemented:
# haskey, getkey, get, get!, delete!, pop!
if (!haskey(db, "x"))
x = get(db, "x", "default")
y = get!(db, "y", "set_value_if_non_exists")
end
end
Support iteration over records, keys and values:
for (k, v) = db
println("k=$k v=$v")
end
for k = keys(db)
println("k=$k")
end
KyotoCabinet treats keys and values as byte arrays. To make it work with arbitrary types, one needs to define pack/unpack methods.
immutable K
x::Int
end
immutable V
a::Int
b::String
end
function KyotoCabinet.pack(k::K)
io = IOBuffer()
write(io, int32(k.x))
takebuf_array(io)
end
function KyotoCabinet.unpack(T::Type{K}, buf::Array{Uint8,1})
io = IOBuffer(buf)
x = read(io, Int32)
K(int(x))
end
function KyotoCabinet.pack(v::V)
io = IOBuffer()
write(io, int32(v.a))
write(io, int32(length(v.b)))
write(io, v.b)
takebuf_array(io)
end
function KyotoCabinet.unpack(T::Type{V}, buf::Array{Uint8,1})
io = IOBuffer(buf)
a = read(io, Int32)
l = read(io, Int32)
b = bytestring(read(io, Uint8, l))
V(int(a), b)
end
After that these types can be used as keys/values:
open(Db{K, V}(), "db.kch", "w+") do db
db[K(1)] = V(1, "a")
db[K(1999999999)] = V(2, repeat("b",100))
end
k = K(1)
println(db[k])
There are also KyotoCabinet specific methods.
# Get the path of the database file
p = path(db)
cas(db::Db, key, old, new)
Compare-and-swap method. Update the value only if it's in the expected state.
Returns true
if value have been updated.
cas(db, "k", "old", "new") # update only if db["k"] == "old"
cas(db, "k", "old", ()) # remove record, only if db["k"] == "old"
cas(db, "k", (), "new") # add record, only if "k" not in db
# Updates records in one operation, atomically if needed.
bulkset!(db, ["a" => "1", "b" => "2"], true)
# Removes records in one operation, atomically if needed.
bulkdelete!(db, ["a", "b"], true)