added operand iterator, beginnings of rustic merge operator

master
Tyler Neely 10 years ago
parent 2d35e4de8d
commit 12c7afad9e
  1. 57
      src/rocksdb.rs

@ -7,7 +7,6 @@ use std::str::from_utf8;
use std::string::raw::from_buf_len;
use std::ptr;
use std::mem;
use std::num;
use std::slice;
use rocksdb_ffi;
@ -359,27 +358,27 @@ fn external() {
extern "C" fn null_destructor(args: *mut c_void) {
println!("in null_destructor");
}
extern "C" fn mo_name(args: *mut c_void) -> *const c_char {
println!("in mo_name");
extern "C" fn mergeoperator_name(args: *mut c_void) -> *const c_char {
println!("in mergeoperator_name");
let name = "test_mo".to_c_str();
unsafe {
let buf = libc::malloc(8 as size_t);
ptr::copy_memory(&mut *buf, name.as_ptr() as *const c_void, 8);
println!("returning from mo_name");
println!("returning from mergeoperator_name");
buf as *const c_char
}
}
struct MergeOperands {
struct MergeOperands<'a> {
operands_list: *const *const c_char,
operands_list_len: *const size_t,
num_operands: uint,
cursor: uint,
}
impl MergeOperands {
fn new(operands_list: *const *const c_char, operands_list_len: *const size_t,
num_operands: c_int) -> MergeOperands {
impl <'a> MergeOperands<'a> {
fn new<'a>(operands_list: *const *const c_char, operands_list_len: *const size_t,
num_operands: c_int) -> MergeOperands<'a> {
assert!(num_operands >= 0);
MergeOperands {
operands_list: operands_list,
@ -390,8 +389,9 @@ impl MergeOperands {
}
}
impl <'a> Iterator<&'a [u8]> for MergeOperands {
impl <'a> Iterator<&'a [u8]> for MergeOperands<'a> {
fn next(&mut self) -> Option<&'a [u8]> {
use std::raw::Slice;
match self.cursor == self.num_operands {
true => None,
false => {
@ -401,17 +401,21 @@ impl <'a> Iterator<&'a [u8]> for MergeOperands {
let spacing = mem::size_of::<*const *const u8>();
let spacing_len = mem::size_of::<*const size_t>();
let len_ptr = (base_len + (spacing_len * self.cursor)) as *const size_t;
let len = *len_ptr;
println!("len: {}", len);
let len = *len_ptr as uint;
let ptr = base + (spacing * self.cursor);
let op = slice::from_raw_buf(*(ptr as *const &*const u8), len as uint);
let op = from_buf_len(*(ptr as *const *const u8), len);
let des: Option<uint> = from_str(op.as_slice());
self.cursor += 1;
println!("returning: {}", from_utf8(op));
Some(op)
Some(mem::transmute(Slice{data:*(ptr as *const *const u8) as *const u8, len: len}))
}
}
}
}
fn size_hint(&self) -> (uint, Option<uint>) {
let remaining = self.num_operands - self.cursor;
(remaining, Some(remaining))
}
}
extern "C" fn full_merge(
@ -422,14 +426,14 @@ extern "C" fn full_merge(
success: *mut u8, new_value_length: *mut size_t) -> *const c_char {
unsafe {
println!("in the FULL merge operator");
/*
for mo in MergeOperands::new(operands_list, operands_list_len, num_operands) {
println!("buf: {}", mo);
}
*/
let oldkey = from_buf_len(key as *const u8, key_len as uint);
let operands = &mut MergeOperands::new(operands_list, operands_list_len, num_operands);
let key = from_buf_len(key as *const u8, key_len as uint);
let oldval = from_buf_len(existing_value as *const u8, existing_value_len as uint);
println!("old key: {}", oldval);
println!("returning from FULL merge");
//TODO rust will "free" this when it goes out of scope, copy this to a non-gc'd buffer to return
merge(key, Some(oldval), operands);
let buf = libc::malloc(1 as size_t);
match buf.is_null() {
false => {
@ -476,6 +480,13 @@ extern "C" fn partial_merge(
}
}
fn merge<'a>(new_key: String, existing_val: Option<String>, operands: &mut MergeOperands) -> &'a [u8] {
for op in *operands {
println!("op: {}", from_utf8(op));
}
"yoyo".as_bytes()
}
#[allow(dead_code)]
#[test]
@ -489,11 +500,10 @@ fn mergetest() {
full_merge,
partial_merge,
None,
mo_name);
mergeoperator_name);
opts.create_if_missing(true);
opts.set_merge_operator(mo);
let db = RocksDB::open(opts, path).unwrap();
println!("here!");
let p = db.put(b"k1", b"1");
assert!(p.is_ok());
db.merge(b"k1", b"10");
@ -502,7 +512,6 @@ fn mergetest() {
db.merge(b"k1", b"4");
let m = db.merge(b"k1", b"5");
assert!(m.is_ok());
println!("after merge");
db.get(b"k1").map( |value| {
match value.to_utf8() {
Some(v) =>

Loading…
Cancel
Save