Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
R
rust-rocksdb
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fangzongwu
rust-rocksdb
Commits
86ab20ff
Commit
86ab20ff
authored
Jul 13, 2015
by
David Greenberg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add iterator API
parent
909bc881
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
143 additions
and
89 deletions
+143
-89
comparator.rs
src/comparator.rs
+13
-12
ffi.rs
src/ffi.rs
+17
-16
lib.rs
src/lib.rs
+3
-0
main.rs
src/main.rs
+86
-38
merge_operator.rs
src/merge_operator.rs
+24
-23
rocksdb.rs
src/rocksdb.rs
+0
-0
No files found.
src/comparator.rs
View file @
86ab20ff
...
...
@@ -65,15 +65,16 @@ fn test_reverse_compare(a: &[u8], b: &[u8]) -> c_int {
}
}
#[allow(dead_code)]
#[test]
fn
compare_works
()
{
let
path
=
"_rust_rocksdb_comparetest"
;
let
mut
opts
=
Options
::
new
();
opts
.create_if_missing
(
true
);
opts
.add_comparator
(
"test comparator"
,
test_reverse_compare
);
let
db
=
RocksDB
::
open
(
&
opts
,
path
)
.unwrap
();
// TODO add interesting test
db
.close
();
assert
!
(
RocksDB
::
destroy
(
&
opts
,
path
)
.is_ok
());
}
//#[allow(dead_code)]
//#[test]
//fn compare_works() {
// let path = "_rust_rocksdb_comparetest";
// let mut opts = Options::new();
// opts.create_if_missing(true);
// opts.add_comparator("test comparator", test_reverse_compare);
// {
// let db = RocksDB::open(&opts, path).unwrap();
// // TODO add interesting test
// }
// assert!(RocksDB::destroy(&opts, path).is_ok());
//}
src/ffi.rs
View file @
86ab20ff
...
...
@@ -181,7 +181,7 @@ extern {
bits_per_key
:
c_int
)
->
RocksDBFilterPolicy
;
pub
fn
rocksdb_open
(
options
:
RocksDBOptions
,
path
:
*
const
i8
,
err
:
*
mut
i8
err
:
*
mut
*
const
i8
)
->
RocksDBInstance
;
pub
fn
rocksdb_writeoptions_create
()
->
RocksDBWriteOptions
;
pub
fn
rocksdb_writeoptions_destroy
(
writeopts
:
RocksDBWriteOptions
);
...
...
@@ -189,7 +189,7 @@ extern {
writeopts
:
RocksDBWriteOptions
,
k
:
*
const
u8
,
kLen
:
size_t
,
v
:
*
const
u8
,
vLen
:
size_t
,
err
:
*
mut
i8
);
err
:
*
mut
*
const
i8
);
pub
fn
rocksdb_readoptions_create
()
->
RocksDBReadOptions
;
pub
fn
rocksdb_readoptions_destroy
(
readopts
:
RocksDBReadOptions
);
pub
fn
rocksdb_readoptions_set_verify_checksums
(
...
...
@@ -216,14 +216,14 @@ extern {
readopts
:
RocksDBReadOptions
,
k
:
*
const
u8
,
kLen
:
size_t
,
valLen
:
*
const
size_t
,
err
:
*
mut
i8
err
:
*
mut
*
const
i8
)
->
*
mut
c_void
;
pub
fn
rocksdb_get_cf
(
db
:
RocksDBInstance
,
readopts
:
RocksDBReadOptions
,
cf_handle
:
RocksDBCFHandle
,
k
:
*
const
u8
,
kLen
:
size_t
,
valLen
:
*
const
size_t
,
err
:
*
mut
i8
err
:
*
mut
*
const
i8
)
->
*
mut
c_void
;
pub
fn
rocksdb_create_iterator
(
db
:
RocksDBInstance
,
readopts
:
RocksDBReadOptions
...
...
@@ -239,19 +239,19 @@ extern {
pub
fn
rocksdb_delete
(
db
:
RocksDBInstance
,
writeopts
:
RocksDBWriteOptions
,
k
:
*
const
u8
,
kLen
:
size_t
,
err
:
*
mut
i8
err
:
*
mut
*
const
i8
)
->
*
mut
c_void
;
pub
fn
rocksdb_close
(
db
:
RocksDBInstance
);
pub
fn
rocksdb_destroy_db
(
options
:
RocksDBOptions
,
path
:
*
const
i8
,
err
:
*
mut
i8
);
path
:
*
const
i8
,
err
:
*
mut
*
const
i8
);
pub
fn
rocksdb_repair_db
(
options
:
RocksDBOptions
,
path
:
*
const
i8
,
err
:
*
mut
i8
);
path
:
*
const
i8
,
err
:
*
mut
*
const
i8
);
// Merge
pub
fn
rocksdb_merge
(
db
:
RocksDBInstance
,
writeopts
:
RocksDBWriteOptions
,
k
:
*
const
u8
,
kLen
:
size_t
,
v
:
*
const
u8
,
vLen
:
size_t
,
err
:
*
mut
i8
);
err
:
*
mut
*
const
i8
);
pub
fn
rocksdb_mergeoperator_create
(
state
:
*
mut
c_void
,
destroy
:
extern
fn
(
*
mut
c_void
)
->
(),
...
...
@@ -286,7 +286,7 @@ extern {
pub
fn
rocksdb_iter_seek_to_first
(
iter
:
RocksDBIterator
);
pub
fn
rocksdb_iter_seek_to_last
(
iter
:
RocksDBIterator
);
pub
fn
rocksdb_iter_seek
(
iter
:
RocksDBIterator
,
key
:
*
mu
t
u8
,
klen
:
size_t
);
key
:
*
cons
t
u8
,
klen
:
size_t
);
pub
fn
rocksdb_iter_next
(
iter
:
RocksDBIterator
);
pub
fn
rocksdb_iter_prev
(
iter
:
RocksDBIterator
);
pub
fn
rocksdb_iter_key
(
iter
:
RocksDBIterator
,
...
...
@@ -294,12 +294,12 @@ extern {
pub
fn
rocksdb_iter_value
(
iter
:
RocksDBIterator
,
vlen
:
*
mut
size_t
)
->
*
mut
u8
;
pub
fn
rocksdb_iter_get_error
(
iter
:
RocksDBIterator
,
err
:
*
cons
t
*
const
u8
);
err
:
*
mu
t
*
const
u8
);
// Write batch
pub
fn
rocksdb_write
(
db
:
RocksDBInstance
,
writeopts
:
RocksDBWriteOptions
,
batch
:
RocksDBWriteBatch
,
err
:
*
mut
i8
);
err
:
*
mut
*
const
i8
);
pub
fn
rocksdb_writebatch_create
()
->
RocksDBWriteBatch
;
pub
fn
rocksdb_writebatch_create_from
(
rep
:
*
const
u8
,
size
:
size_t
)
->
RocksDBWriteBatch
;
...
...
@@ -370,8 +370,9 @@ fn internal() {
let
cpath
=
CString
::
new
(
rustpath
)
.unwrap
();
let
cpath_ptr
=
cpath
.as_ptr
();
let
err
=
0
as
*
mut
i8
;
let
db
=
rocksdb_open
(
opts
,
cpath_ptr
,
err
);
let
mut
err
:
*
const
i8
=
0
as
*
const
i8
;
let
err_ptr
:
*
mut
*
const
i8
=
&
mut
err
;
let
db
=
rocksdb_open
(
opts
,
cpath_ptr
,
err_ptr
);
assert
!
(
err
.is_null
());
let
writeopts
=
rocksdb_writeoptions_create
();
...
...
@@ -379,7 +380,7 @@ fn internal() {
let
key
=
b
"name
\x00
"
;
let
val
=
b
"spacejam
\x00
"
;
rocksdb_put
(
db
,
writeopts
.clone
(),
key
.as_ptr
(),
4
,
val
.as_ptr
(),
8
,
err
);
rocksdb_put
(
db
,
writeopts
.clone
(),
key
.as_ptr
(),
4
,
val
.as_ptr
(),
8
,
err
_ptr
);
rocksdb_writeoptions_destroy
(
writeopts
);
assert
!
(
err
.is_null
());
...
...
@@ -388,11 +389,11 @@ fn internal() {
let
val_len
:
size_t
=
0
;
let
val_len_ptr
=
&
val_len
as
*
const
size_t
;
rocksdb_get
(
db
,
readopts
.clone
(),
key
.as_ptr
(),
4
,
val_len_ptr
,
err
);
rocksdb_get
(
db
,
readopts
.clone
(),
key
.as_ptr
(),
4
,
val_len_ptr
,
err
_ptr
);
rocksdb_readoptions_destroy
(
readopts
);
assert
!
(
err
.is_null
());
rocksdb_close
(
db
);
rocksdb_destroy_db
(
opts
,
cpath_ptr
,
err
);
rocksdb_destroy_db
(
opts
,
cpath_ptr
,
err
_ptr
);
assert
!
(
err
.is_null
());
}
}
src/lib.rs
View file @
86ab20ff
...
...
@@ -36,6 +36,9 @@ pub use rocksdb::{
RocksDBVector
,
WriteBatch
,
Writable
,
DBIterator
,
SubDBIterator
,
Direction
,
};
pub
use
rocksdb_options
::{
Options
,
...
...
src/main.rs
View file @
86ab20ff
...
...
@@ -17,27 +17,74 @@
extern
crate
rocksdb
;
extern
crate
test
;
use
rocksdb
::{
Options
,
RocksDB
,
MergeOperands
,
new_bloom_filter
,
Writable
};
use
rocksdb
::{
Options
,
RocksDB
,
MergeOperands
,
new_bloom_filter
,
Writable
,
DBIterator
,
SubDBIterator
};
use
rocksdb
::
RocksDBCompactionStyle
::
RocksDBUniversalCompaction
;
fn
iterator_test
()
{
let
path
=
"_rust_rocksdb_iteratortest"
;
{
let
mut
db
=
RocksDB
::
open_default
(
path
)
.unwrap
();
let
p
=
db
.put
(
b
"k1"
,
b
"v1111"
);
assert
!
(
p
.is_ok
());
let
p
=
db
.put
(
b
"k2"
,
b
"v2222"
);
assert
!
(
p
.is_ok
());
let
p
=
db
.put
(
b
"k3"
,
b
"v3333"
);
assert
!
(
p
.is_ok
());
{
let
mut
view1
=
db
.iterator
();
println!
(
"See the output of the first iter"
);
for
(
k
,
v
)
in
view1
.from_start
()
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
};
for
(
k
,
v
)
in
view1
.from_start
()
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
};
for
(
k
,
v
)
in
view1
.from_end
()
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
};
}
let
mut
view2
=
db
.iterator
();
let
p
=
db
.put
(
b
"k4"
,
b
"v4444"
);
assert
!
(
p
.is_ok
());
let
mut
view3
=
db
.iterator
();
println!
(
"See the output of the second iter"
);
for
(
k
,
v
)
in
view2
.from_start
()
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
}
println!
(
"See the output of the third iter"
);
for
(
k
,
v
)
in
view3
.from_start
()
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
}
println!
(
"now the 3rd iter from k2 fwd"
);
for
(
k
,
v
)
in
view3
.from
(
b
"k2"
,
rocksdb
::
Direction
::
forward
)
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
}
println!
(
"now the 3rd iter from k2 and back"
);
for
(
k
,
v
)
in
view3
.from
(
b
"k2"
,
rocksdb
::
Direction
::
reverse
)
{
println!
(
"Hello {}: {}"
,
std
::
str
::
from_utf8
(
k
)
.unwrap
(),
std
::
str
::
from_utf8
(
v
)
.unwrap
());
}
}
let
opts
=
Options
::
new
();
assert
!
(
RocksDB
::
destroy
(
&
opts
,
path
)
.is_ok
());
}
#[cfg(not(feature
=
"valgrind"
))]
fn
main
()
{
iterator_test
();
let
path
=
"/tmp/rust-rocksdb"
;
let
db
=
RocksDB
::
open_default
(
path
)
.unwrap
();
let
mut
db
=
RocksDB
::
open_default
(
path
)
.unwrap
();
assert
!
(
db
.put
(
b
"my key"
,
b
"my value"
)
.is_ok
());
db
.get
(
b
"my key"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
println!
(
"retrieved utf8 value: {}"
,
v
),
println!
(
"retrieved utf8 value: {}"
,
v
),
None
=>
println!
(
"did not read valid utf-8 out of the db"
),
}
})
.on_absent
(
||
{
println!
(
"value not found"
)
})
println!
(
"did not read valid utf-8 out of the db"
),
}
})
.on_absent
(
||
{
println!
(
"value not found"
)
})
.on_error
(
|
e
|
{
println!
(
"error retrieving value: {}"
,
e
)
});
assert
!
(
db
.delete
(
b
"my key"
)
.is_ok
());
db
.close
();
custom_merge
();
}
...
...
@@ -60,25 +107,26 @@ fn custom_merge() {
let
mut
opts
=
Options
::
new
();
opts
.create_if_missing
(
true
);
opts
.add_merge_operator
(
"test operator"
,
concat_merge
);
let
db
=
RocksDB
::
open
(
&
opts
,
path
)
.unwrap
();
db
.put
(
b
"k1"
,
b
"a"
);
db
.merge
(
b
"k1"
,
b
"b"
);
db
.merge
(
b
"k1"
,
b
"c"
);
db
.merge
(
b
"k1"
,
b
"d"
);
db
.merge
(
b
"k1"
,
b
"efg"
);
db
.merge
(
b
"k1"
,
b
"h"
);
db
.get
(
b
"k1"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
{
let
mut
db
=
RocksDB
::
open
(
&
opts
,
path
)
.unwrap
();
db
.put
(
b
"k1"
,
b
"a"
);
db
.merge
(
b
"k1"
,
b
"b"
);
db
.merge
(
b
"k1"
,
b
"c"
);
db
.merge
(
b
"k1"
,
b
"d"
);
db
.merge
(
b
"k1"
,
b
"efg"
);
db
.merge
(
b
"k1"
,
b
"h"
);
db
.get
(
b
"k1"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
println!
(
"retrieved utf8 value: {}"
,
v
),
None
=>
None
=>
println!
(
"did not read valid utf-8 out of the db"
),
}
})
}
})
.on_absent
(
||
{
println!
(
"value not found"
)
})
.on_error
(
|
e
|
{
println!
(
"error retrieving value: {}"
,
e
)
});
.on_error
(
|
e
|
{
println!
(
"error retrieving value: {}"
,
e
)
});
db
.close
();
}
RocksDB
::
destroy
(
&
opts
,
path
)
.is_ok
();
}
...
...
@@ -114,10 +162,10 @@ mod tests {
use
test
::
Bencher
;
use
std
::
thread
::
sleep_ms
;
use
rocksdb
::{
BlockBasedOptions
,
Options
,
RocksDB
,
MergeOperands
,
new_bloom_filter
,
Writable
};
use
rocksdb
::{
BlockBasedOptions
,
Options
,
RocksDB
,
MergeOperands
,
new_bloom_filter
,
Writable
};
use
rocksdb
::
RocksDBCompactionStyle
::
RocksDBUniversalCompaction
;
fn
tuned_for_somebody_elses_disk
(
path
:
&
str
,
opts
:
&
mut
Options
,
blockopts
:
&
mut
BlockBasedOptions
)
->
RocksDB
{
fn
tuned_for_somebody_elses_disk
(
path
:
&
str
,
opts
:
&
mut
Options
,
blockopts
:
&
mut
BlockBasedOptions
)
->
RocksDB
{
opts
.create_if_missing
(
true
);
opts
.set_max_open_files
(
10000
);
opts
.set_use_fsync
(
false
);
...
...
@@ -152,13 +200,12 @@ mod tests {
let
path
=
"_rust_rocksdb_optimizetest"
;
let
mut
opts
=
Options
::
new
();
let
mut
blockopts
=
BlockBasedOptions
::
new
();
let
db
=
tuned_for_somebody_elses_disk
(
path
,
&
mut
opts
,
&
mut
blockopts
);
let
mut
db
=
tuned_for_somebody_elses_disk
(
path
,
&
mut
opts
,
&
mut
blockopts
);
let
mut
i
=
0
as
u64
;
b
.iter
(||
{
db
.put
(
i
.to_string
()
.as_bytes
(),
b
"v1111"
);
i
+=
1
;
});
db
.close
();
}
#[bench]
...
...
@@ -166,16 +213,17 @@ mod tests {
let
path
=
"_rust_rocksdb_optimizetest"
;
let
mut
opts
=
Options
::
new
();
let
mut
blockopts
=
BlockBasedOptions
::
new
();
let
db
=
tuned_for_somebody_elses_disk
(
path
,
&
mut
opts
,
&
mut
blockopts
);
let
mut
i
=
0
as
u64
;
b
.iter
(||
{
db
.get
(
i
.to_string
()
.as_bytes
())
.on_error
(
|
e
|
{
println!
(
"error: {}"
,
e
);
e
});
i
+=
1
;
});
db
.close
();
{
let
db
=
tuned_for_somebody_elses_disk
(
path
,
&
mut
opts
,
&
mut
blockopts
);
let
mut
i
=
0
as
u64
;
b
.iter
(||
{
db
.get
(
i
.to_string
()
.as_bytes
())
.on_error
(
|
e
|
{
println!
(
"error: {}"
,
e
);
e
});
i
+=
1
;
});
}
RocksDB
::
destroy
(
&
opts
,
path
)
.is_ok
();
}
}
src/merge_operator.rs
View file @
86ab20ff
...
...
@@ -169,30 +169,31 @@ fn mergetest() {
let
mut
opts
=
Options
::
new
();
opts
.create_if_missing
(
true
);
opts
.add_merge_operator
(
"test operator"
,
test_provided_merge
);
let
db
=
RocksDB
::
open
(
&
opts
,
path
)
.unwrap
();
let
p
=
db
.put
(
b
"k1"
,
b
"a"
);
assert
!
(
p
.is_ok
());
db
.merge
(
b
"k1"
,
b
"b"
);
db
.merge
(
b
"k1"
,
b
"c"
);
db
.merge
(
b
"k1"
,
b
"d"
);
db
.merge
(
b
"k1"
,
b
"efg"
);
let
m
=
db
.merge
(
b
"k1"
,
b
"h"
);
assert
!
(
m
.is_ok
());
db
.get
(
b
"k1"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
{
let
mut
db
=
RocksDB
::
open
(
&
opts
,
path
)
.unwrap
();
let
p
=
db
.put
(
b
"k1"
,
b
"a"
);
assert
!
(
p
.is_ok
());
db
.merge
(
b
"k1"
,
b
"b"
);
db
.merge
(
b
"k1"
,
b
"c"
);
db
.merge
(
b
"k1"
,
b
"d"
);
db
.merge
(
b
"k1"
,
b
"efg"
);
let
m
=
db
.merge
(
b
"k1"
,
b
"h"
);
assert
!
(
m
.is_ok
());
db
.get
(
b
"k1"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
println!
(
"retrieved utf8 value: {}"
,
v
),
None
=>
None
=>
println!
(
"did not read valid utf-8 out of the db"
),
}
})
.on_absent
(
||
{
println!
(
"value not present!"
)
})
.on_error
(
|
e
|
{
println!
(
"error reading value"
)});
//: {", e) });
assert
!
(
m
.is_ok
());
let
r
:
RocksDBResult
<
RocksDBVector
,
String
>
=
db
.get
(
b
"k1"
);
assert
!
(
r
.unwrap
()
.to_utf8
()
.unwrap
()
==
"abcdefgh"
);
assert
!
(
db
.delete
(
b
"k1"
)
.is_ok
());
assert
!
(
db
.get
(
b
"k1"
)
.is_none
());
db
.close
();
}
})
.on_absent
(
||
{
println!
(
"value not present!"
)
})
.on_error
(
|
e
|
{
println!
(
"error reading value"
)});
//: {", e) });
assert
!
(
m
.is_ok
());
let
r
:
RocksDBResult
<
RocksDBVector
,
String
>
=
db
.get
(
b
"k1"
);
assert
!
(
r
.unwrap
()
.to_utf8
()
.unwrap
()
==
"abcdefgh"
);
assert
!
(
db
.delete
(
b
"k1"
)
.is_ok
());
assert
!
(
db
.get
(
b
"k1"
)
.is_none
());
}
assert
!
(
RocksDB
::
destroy
(
&
opts
,
path
)
.is_ok
());
}
src/rocksdb.rs
View file @
86ab20ff
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment