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
e1142f4f
Commit
e1142f4f
authored
Nov 28, 2014
by
Tyler Neely
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
some cleanups and interface smoothing
parent
59af6610
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
143 additions
and
123 deletions
+143
-123
README.md
README.md
+22
-12
lib.rs
rocksdb-sys/lib.rs
+4
-4
lib.rs
src/lib.rs
+1
-0
main.rs
src/main.rs
+18
-4
rocksdb.rs
src/rocksdb.rs
+98
-103
No files found.
README.md
View file @
e1142f4f
...
...
@@ -4,22 +4,32 @@ rust-rocksdb
### running
-
Cargo.toml
```
rust
[
dependencies
.rocksdb
]
[
dependencies
.rocksdb
]
git
=
"https://github.com/spacejam/rust-rocksdb"
```
-
Code
```
rust
extern
crate
rocksdb
;
fn
main
()
{
let
db
=
rocksdb
::
open
(
"/path/to/db"
.to_string
(),
true
)
.unwrap
();
assert
!
(
db
.put
(
b
"hey"
,
b
"v1111"
)
.is_ok
());
db
.get
(
b
"hey"
)
.map
(
|
raw
|
{
std
::
str
::
from_utf8
(
raw
.as_slice
())
.map
(
|
v
|
{
println!
(
"value: {}"
,
v
);
})
});
db
.close
()
extern
crate
rocksdb
;
fn
main
()
{
match
rocksdb
::
create_or_open
(
"/path/for/rocksdb/storage"
.to_string
())
{
Ok
(
db
)
=>
{
db
.put
(
b
"my key"
,
b
"my value"
);
db
.get
(
b
"my key"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
println!
(
"retrieved utf8 value {}"
,
v
),
None
=>
println!
(
"did not read valid utf-8 out of the db"
),
}});
db
.get
(
b
"NOT my key"
)
.on_absent
(||
{
println!
(
"value not found"
)
});
db
.close
();
},
Err
(
e
)
=>
panic!
(
e
),
}
}
```
...
...
rocksdb-sys/lib.rs
View file @
e1142f4f
...
...
@@ -105,7 +105,7 @@ extern {
pub
fn
rocksdb_readoptions_create
()
->
RocksdbReadOptions
;
pub
fn
rocksdb_get
(
db
:
RocksdbInstance
,
readopts
:
RocksdbReadOptions
,
k
:
*
const
u8
,
kLen
:
size_t
,
valLen
:
*
const
size_t
,
err
:
*
mut
i8
)
->
*
mut
u8
;
valLen
:
*
const
size_t
,
err
:
*
mut
i8
)
->
*
mut
c_void
;
pub
fn
rocksdb_close
(
db
:
RocksdbInstance
);
pub
fn
rocksdb_destroy_db
(
options
:
RocksdbOptions
,
path
:
*
const
i8
,
err
:
*
mut
i8
);
...
...
@@ -122,7 +122,7 @@ fn internal() {
let
opts
=
rocksdb_options_create
();
let
RocksdbOptions
(
opt_ptr
)
=
opts
;
assert
!
(
opt_ptr
.is_not_null
());
rocksdb_options_increase_parallelism
(
opts
,
0
);
rocksdb_options_optimize_level_style_compaction
(
opts
,
0
);
rocksdb_options_set_create_if_missing
(
opts
,
1
);
...
...
@@ -130,9 +130,9 @@ fn internal() {
let
rustpath
=
"internaltest"
;
let
cpath
=
rustpath
.to_c_str
();
let
cpath_ptr
=
cpath
.as_ptr
();
let
err
=
0
as
*
mut
i8
;
let
db
=
rocksdb_open
(
opts
,
cpath_ptr
,
err
);
let
db
=
rocksdb_open
(
opts
,
cpath_ptr
,
err
);
assert
!
(
err
.is_null
());
libc
::
free
(
err
as
*
mut
c_void
);
...
...
src/lib.rs
View file @
e1142f4f
...
...
@@ -5,6 +5,7 @@
extern
crate
"rocksdb-sys"
as
rocksdb_ffi
;
pub
use
rocksdb
::{
create_or_open
,
open
,
Rocksdb
,
RocksdbResult
,
...
...
src/main.rs
View file @
e1142f4f
...
...
@@ -5,10 +5,24 @@ use test::Bencher;
#[allow(dead_code)]
fn
main
()
{
let
db
=
open
(
"testdb"
.to_string
(),
true
)
.unwrap
();
assert
!
(
db
.put
(
b
"hey"
,
b
"v1111"
)
.is_ok
());
db
.get
(
b
"hey"
)
.map
(|
raw
|
{
std
::
str
::
from_utf8
(
raw
.as_slice
())
.map
(|
v
|
{
println!
(
"value: {}"
,
v
);
})});
db
.close
();
match
rocksdb
::
create_or_open
(
"/tmp/rust-rocksdb"
.to_string
())
{
Ok
(
db
)
=>
{
db
.put
(
b
"my key"
,
b
"my value"
);
db
.get
(
b
"my key"
)
.map
(
|
value
|
{
match
value
.to_utf8
()
{
Some
(
v
)
=>
println!
(
"retrieved utf8 value {}"
,
v
),
None
=>
println!
(
"did not read valid utf-8 out of the db"
),
}});
db
.get
(
b
"NOT my key"
)
.on_absent
(||
{
println!
(
"value not found"
)
});
db
.close
();
},
Err
(
e
)
=>
panic!
(
e
),
}
}
#[allow(dead_code)]
...
...
src/rocksdb.rs
View file @
e1142f4f
...
...
@@ -3,13 +3,85 @@ use self::libc::{c_void, size_t};
use
std
::
io
::{
IoError
};
use
std
::
c_vec
::
CVec
;
use
std
::
c_str
::
CString
;
use
std
::
str
::
from_utf8
;
use
rocksdb_ffi
;
// TODO learn more about lifetimes and determine if it's appropriate to keep
// inner on the stack, instead.
pub
struct
Rocksdb
{
inner
:
rocksdb_ffi
::
RocksdbInstance
,
}
impl
Rocksdb
{
pub
fn
put
(
&
self
,
key
:
&
[
u8
],
value
:
&
[
u8
])
->
Result
<
(),
String
>
{
unsafe
{
let
writeopts
=
rocksdb_ffi
::
rocksdb_writeoptions_create
();
let
err
=
0
as
*
mut
i8
;
rocksdb_ffi
::
rocksdb_put
(
self
.inner
,
writeopts
,
key
.as_ptr
(),
key
.len
()
as
size_t
,
value
.as_ptr
(),
value
.len
()
as
size_t
,
err
);
if
err
.is_not_null
()
{
let
cs
=
CString
::
new
(
err
as
*
const
i8
,
true
);
match
cs
.as_str
()
{
Some
(
error_string
)
=>
return
Err
(
error_string
.to_string
()),
None
=>
{
let
ie
=
IoError
::
last_error
();
return
Err
(
format!
(
"ERROR: desc:{}, details:{}"
,
ie
.desc
,
ie
.detail
.unwrap_or_else
(
||
{
"none provided by OS"
.to_string
()})))
}
}
}
return
Ok
(())
}
}
pub
fn
get
<
'a
>
(
&
self
,
key
:
&
[
u8
])
->
RocksdbResult
<
'a
,
RocksdbVector
,
String
>
{
unsafe
{
let
readopts
=
rocksdb_ffi
::
rocksdb_readoptions_create
();
let
rocksdb_ffi
::
RocksdbReadOptions
(
read_opts_ptr
)
=
readopts
;
if
read_opts_ptr
.is_null
()
{
return
RocksdbResult
::
Error
(
"Unable to create rocksdb read
\
options. This is a fairly trivial call, and its failure
\
may be indicative of a mis-compiled or mis-loaded rocksdb
\
library."
.to_string
());
}
let
val_len
:
size_t
=
0
;
let
val_len_ptr
=
&
val_len
as
*
const
size_t
;
let
err
=
0
as
*
mut
i8
;
let
val
=
rocksdb_ffi
::
rocksdb_get
(
self
.inner
,
readopts
,
key
.as_ptr
(),
key
.len
()
as
size_t
,
val_len_ptr
,
err
)
as
*
mut
u8
;
if
err
.is_not_null
()
{
let
cs
=
CString
::
new
(
err
as
*
const
i8
,
true
);
match
cs
.as_str
()
{
Some
(
error_string
)
=>
return
RocksdbResult
::
Error
(
error_string
.to_string
()),
None
=>
return
RocksdbResult
::
Error
(
"Unable to get value from
\
rocksdb. (non-utf8 error received from underlying
\
library)"
.to_string
()),
}
}
match
val
.is_null
()
{
true
=>
RocksdbResult
::
None
,
false
=>
{
RocksdbResult
::
Some
(
RocksdbVector
::
from_c
(
val
,
val_len
))
}
}
}
}
pub
fn
close
(
&
self
)
{
unsafe
{
rocksdb_ffi
::
rocksdb_close
(
self
.inner
);
}
}
}
pub
struct
RocksdbVector
{
inner
:
Box
<
CVec
<
u8
>
>
,
inner
:
CVec
<
u8
>
,
}
impl
RocksdbVector
{
...
...
@@ -17,50 +89,31 @@ impl RocksdbVector {
unsafe
{
RocksdbVector
{
inner
:
box
CVec
::
new_with_dtor
(
val
,
val_len
as
uint
,
proc
(){
libc
::
free
(
val
as
*
mut
c_void
);
})
CVec
::
new_with_dtor
(
val
,
val_len
as
uint
,
proc
(){
libc
::
free
(
val
as
*
mut
c_void
);
})
}
}
}
pub
fn
as_slice
(
&
self
)
->
&
[
u8
]
{
pub
fn
as_slice
<
'a
>
(
&
'a
self
)
->
&
'a
[
u8
]
{
self
.inner
.as_slice
()
}
pub
fn
to_utf8
<
'a
>
(
&
'a
self
)
->
Option
<&
'a
str
>
{
from_utf8
(
self
.inner
.as_slice
())
}
}
// RocksdbResult exists because of the inherent difference between
// an operational failure and the absence of a possible result.
#[deriving(Clone,
PartialEq,
PartialOrd,
Eq,
Ord,
Show)]
pub
enum
RocksdbResult
<
T
,
E
>
{
pub
enum
RocksdbResult
<
'a
,
T
,
E
>
{
Some
(
T
),
None
,
Error
(
E
),
}
/*
impl <E> RocksdbResult<Box<CVec<u8>>, E> {
pub fn from_c(val: *mut u8, val_len: size_t) -> RocksdbResult<Box<CVec<u8>>, E> {
unsafe {
RocksdbResult::Some(
box CVec::new_with_dtor(val, val_len as uint,
proc(){
libc::free(val as *mut c_void);
}))
}
}
pub fn as_slice<'a>(self) -> Option<&'a [u8]> {
match self {
RocksdbResult::Some(x) => Some(x.as_slice()),
RocksdbResult::None => None,
RocksdbResult::Error(e) => None,
}
}
}
*/
impl
<
T
,
E
>
RocksdbResult
<
T
,
E
>
{
impl
<
'a
,
T
,
E
>
RocksdbResult
<
'a
,
T
,
E
>
{
#[unstable
=
"waiting for unboxed closures"
]
pub
fn
map
<
U
>
(
self
,
f
:
|
T
|
->
U
)
->
RocksdbResult
<
U
,
E
>
{
match
self
{
...
...
@@ -70,6 +123,14 @@ impl <T,E> RocksdbResult<T,E> {
}
}
pub
fn
unwrap
(
self
)
->
T
{
match
self
{
RocksdbResult
::
Some
(
x
)
=>
x
,
RocksdbResult
::
None
=>
panic!
(
"Attempted unwrap on RocksdbResult::None"
),
RocksdbResult
::
Error
(
_
)
=>
panic!
(
"Attempted unwrap on RocksdbResult::Error"
),
}
}
#[unstable
=
"waiting for unboxed closures"
]
pub
fn
on_error
<
U
>
(
self
,
f
:
|
E
|
->
U
)
->
RocksdbResult
<
T
,
U
>
{
match
self
{
...
...
@@ -80,7 +141,7 @@ impl <T,E> RocksdbResult<T,E> {
}
#[unstable
=
"waiting for unboxed closures"
]
pub
fn
on_absent
<
U
>
(
self
,
f
:
||
->
())
->
RocksdbResult
<
T
,
E
>
{
pub
fn
on_absent
(
self
,
f
:
||
->
())
->
RocksdbResult
<
T
,
E
>
{
match
self
{
RocksdbResult
::
Some
(
x
)
=>
RocksdbResult
::
Some
(
x
),
RocksdbResult
::
None
=>
{
...
...
@@ -114,77 +175,8 @@ impl <T,E> RocksdbResult<T,E> {
}
}
pub
struct
Rocksdb
{
inner
:
rocksdb_ffi
::
RocksdbInstance
,
}
impl
Rocksdb
{
pub
fn
put
(
&
self
,
key
:
&
[
u8
],
value
:
&
[
u8
])
->
Result
<
bool
,
String
>
{
unsafe
{
let
writeopts
=
rocksdb_ffi
::
rocksdb_writeoptions_create
();
let
err
=
0
as
*
mut
i8
;
rocksdb_ffi
::
rocksdb_put
(
self
.inner
,
writeopts
,
key
.as_ptr
(),
key
.len
()
as
size_t
,
value
.as_ptr
(),
value
.len
()
as
size_t
,
err
);
if
err
.is_not_null
()
{
let
cs
=
CString
::
new
(
err
as
*
const
i8
,
true
);
match
cs
.as_str
()
{
Some
(
error_string
)
=>
return
Err
(
error_string
.to_string
()),
None
=>
{
let
ie
=
IoError
::
last_error
();
return
Err
(
format!
(
"ERROR: desc:{}, details:{}"
,
ie
.desc
,
ie
.detail
.unwrap_or_else
(
||
{
"none provided by OS"
.to_string
()})))
}
}
}
return
Ok
(
true
)
}
}
pub
fn
get
(
&
self
,
key
:
&
[
u8
])
->
RocksdbResult
<
RocksdbVector
,
String
>
{
unsafe
{
let
readopts
=
rocksdb_ffi
::
rocksdb_readoptions_create
();
let
rocksdb_ffi
::
RocksdbReadOptions
(
read_opts_ptr
)
=
readopts
;
if
read_opts_ptr
.is_null
()
{
return
RocksdbResult
::
Error
(
"Unable to create rocksdb read
\
options. This is a fairly trivial call, and its failure
\
may be indicative of a mis-compiled or mis-loaded rocksdb
\
library."
.to_string
());
}
let
val_len
:
size_t
=
0
;
let
val_len_ptr
=
&
val_len
as
*
const
size_t
;
let
err
=
0
as
*
mut
i8
;
let
val
=
rocksdb_ffi
::
rocksdb_get
(
self
.inner
,
readopts
,
key
.as_ptr
(),
key
.len
()
as
size_t
,
val_len_ptr
,
err
);
if
err
.is_not_null
()
{
let
cs
=
CString
::
new
(
err
as
*
const
i8
,
true
);
match
cs
.as_str
()
{
Some
(
error_string
)
=>
return
RocksdbResult
::
Error
(
error_string
.to_string
()),
None
=>
return
RocksdbResult
::
Error
(
"Unable to get value from
\
rocksdb. (non-utf8 error received from underlying
\
library)"
.to_string
()),
}
}
match
val
.is_null
()
{
true
=>
RocksdbResult
::
None
,
false
=>
{
RocksdbResult
::
Some
(
RocksdbVector
::
from_c
(
val
,
val_len
))
}
}
}
}
pub
fn
close
(
&
self
)
{
unsafe
{
rocksdb_ffi
::
rocksdb_close
(
self
.inner
);
}
}
pub
fn
create_or_open
(
path
:
String
)
->
Result
<
Rocksdb
,
String
>
{
open
(
path
,
true
)
}
pub
fn
open
(
path
:
String
,
create_if_missing
:
bool
)
->
Result
<
Rocksdb
,
String
>
{
...
...
@@ -206,6 +198,9 @@ pub fn open(path: String, create_if_missing: bool) -> Result<Rocksdb, String> {
let
cpath
=
path
.to_c_str
();
let
cpath_ptr
=
cpath
.as_ptr
();
//TODO test path here, as if rocksdb fails it will just crash the
// process currently
let
err
=
0
as
*
mut
i8
;
let
db
=
rocksdb_ffi
::
rocksdb_open
(
opts
,
cpath_ptr
,
err
);
let
rocksdb_ffi
::
RocksdbInstance
(
db_ptr
)
=
db
;
...
...
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