From e6cf52194abf6c2683edc0977782c16f3661e99f Mon Sep 17 00:00:00 2001 From: Jihyun Yu Date: Sat, 4 Apr 2020 01:29:18 +0900 Subject: [PATCH 1/3] rustfmt --- src/lib.rs | 191 +++++++++++++++++++++++++++++------------------------ 1 file changed, 103 insertions(+), 88 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 49c02ee..3e5b30c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,16 +1,15 @@ -#[allow(non_camel_case_types,dead_code,non_snake_case,private_in_public)] +#[allow(non_camel_case_types, dead_code, non_snake_case, private_in_public)] extern crate traildb_sys; -use std::path::Path; +use std::cell::RefCell; use std::ffi::CString; use std::fmt; -use std::mem::{transmute, forget}; -use std::cell::RefCell; +use std::mem::{forget, transmute}; +use std::path::Path; use std::collections::HashMap; -#[derive(Debug)] -#[derive(PartialEq)] +#[derive(Debug, PartialEq)] #[repr(C)] pub enum Error { Nomem = -2, @@ -112,15 +111,13 @@ pub type TrailId = u64; pub type Uuid = [u8; 16]; /// TODO: Document me -#[derive(Debug,Clone,Copy,PartialEq,Eq,Hash)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub struct Item(pub u64); /// TODO: Document me pub type Value = u64; /// TODO: Document me pub type Field = u32; - - /// A structure that represents a `TrailDB` constructor. /// /// A constructor lives in RAM. All events are added to the constructor. @@ -160,7 +157,6 @@ pub struct Constructor { impl Constructor { /// Create a new TrailDB constructor. pub fn new(path: &Path, fields: &[&str]) -> Result { - let mut field_ptrs = Vec::new(); for f in fields.iter() { let s = CString::new(*f).unwrap(); @@ -170,10 +166,12 @@ impl Constructor { let ptr = unsafe { traildb_sys::tdb_cons_init() }; let ret = unsafe { - traildb_sys::tdb_cons_open(ptr, - path_cstr(path).as_ptr(), - field_ptrs.as_slice().as_ptr() as *mut *const i8, - field_ptrs.len() as u64) + traildb_sys::tdb_cons_open( + ptr, + path_cstr(path).as_ptr(), + field_ptrs.as_slice().as_ptr() as *mut *const i8, + field_ptrs.len() as u64, + ) }; wrap_tdb_err(ret, Constructor { obj: ptr }) } @@ -187,11 +185,13 @@ impl Constructor { val_lens.push(v.len() as u64); } let ret = unsafe { - traildb_sys::tdb_cons_add(self.obj, - uuid.as_ptr() as *mut u8, - timestamp, - val_ptrs.as_slice().as_ptr() as *mut *const i8, - val_lens.as_slice().as_ptr() as *const u64) + traildb_sys::tdb_cons_add( + self.obj, + uuid.as_ptr() as *mut u8, + timestamp, + val_ptrs.as_slice().as_ptr() as *mut *const i8, + val_lens.as_slice().as_ptr() as *const u64, + ) }; wrap_tdb_err(ret, ()) } @@ -220,7 +220,6 @@ impl Drop for Constructor { } } - pub struct Db<'a> { obj: &'a mut traildb_sys::tdb, } @@ -229,7 +228,14 @@ impl<'a> Db<'a> { pub fn open>(path: P) -> Result { let ptr = unsafe { traildb_sys::tdb_init() }; let ret = unsafe { traildb_sys::tdb_open(ptr, path_cstr(path).as_ptr()) }; - unsafe { wrap_tdb_err(ret, Db { obj: transmute(ptr) }) } + unsafe { + wrap_tdb_err( + ret, + Db { + obj: transmute(ptr), + }, + ) + } } pub fn close(&mut self) { @@ -284,7 +290,11 @@ impl<'a> Db<'a> { pub fn get_trail_id(&self, uuid: &Uuid) -> Option { let mut id: TrailId = 0; let ret = unsafe { - traildb_sys::tdb_get_trail_id(self.obj, uuid.as_ptr() as *mut u8, &mut id as *mut TrailId) + traildb_sys::tdb_get_trail_id( + self.obj, + uuid.as_ptr() as *mut u8, + &mut id as *mut TrailId, + ) }; match ret { traildb_sys::tdb_error_TDB_ERR_OK => Some(id), @@ -302,7 +312,9 @@ impl<'a> Db<'a> { pub fn cursor(&'a self) -> Cursor<'a> { unsafe { let ptr = traildb_sys::tdb_cursor_new(self.obj); - Cursor { obj: transmute(ptr) } + Cursor { + obj: transmute(ptr), + } } } @@ -325,12 +337,18 @@ impl<'a> Db<'a> { pub fn get_item(&'a self, field: Field, value: &str) -> Option { unsafe { - let item = traildb_sys::tdb_get_item(self.obj, - transmute(field), - value.as_ptr() as *const i8, - value.len() as u64); - - if item == 0 { None } else { Some(Item(item)) } + let item = traildb_sys::tdb_get_item( + self.obj, + transmute(field), + value.as_ptr() as *const i8, + value.len() as u64, + ); + + if item == 0 { + None + } else { + Some(Item(item)) + } } } @@ -375,16 +393,12 @@ impl<'a> Db<'a> { } } - impl<'a> Drop for Db<'a> { fn drop(&mut self) { unsafe { traildb_sys::tdb_close(self.obj) }; } } - - - pub struct DbIter<'a> { pos: u64, db: &'a Db<'a>, @@ -410,8 +424,6 @@ impl<'a> Iterator for DbIter<'a> { } } - - /// A cursor allows you to iterate over the events in a single trail, /// decoding a batch from the optimized storage format when necessary. /// @@ -423,8 +435,6 @@ pub struct Cursor<'a> { obj: &'a mut traildb_sys::tdb_cursor, } - - impl<'a> Cursor<'a> { pub fn get_trail(&mut self, trail_id: TrailId) -> Result<(), Error> { let ret = unsafe { traildb_sys::tdb_get_trail(self.obj, trail_id) }; @@ -480,10 +490,13 @@ impl<'a> MultiCursor<'a> { } unsafe { - let ptr = traildb_sys::tdb_multi_cursor_new(ptrs.as_slice().as_ptr() as - *mut *mut traildb_sys::tdb_cursor, - ptrs.len() as u64); - MultiCursor { obj: transmute(ptr) } + let ptr = traildb_sys::tdb_multi_cursor_new( + ptrs.as_slice().as_ptr() as *mut *mut traildb_sys::tdb_cursor, + ptrs.len() as u64, + ); + MultiCursor { + obj: transmute(ptr), + } } } @@ -509,9 +522,6 @@ impl<'a> Iterator for MultiCursor<'a> { } } - - - pub struct Trail<'a> { pub id: TrailId, cursor: Cursor<'a>, @@ -525,15 +535,10 @@ impl<'a> Iterator for Trail<'a> { } } - - - fn path_cstr>(path: P) -> CString { CString::new(path.as_ref().to_str().unwrap()).unwrap() } - - #[derive(Debug)] pub struct Event<'a> { pub timestamp: Timestamp, @@ -545,13 +550,10 @@ impl<'a> Event<'a> { unsafe { match e.as_ref() { None => None, - Some(e) => { - Some(Event { - timestamp: e.timestamp, - items: std::slice::from_raw_parts(transmute(&e.items), - e.num_items as usize), - }) - } + Some(e) => Some(Event { + timestamp: e.timestamp, + items: std::slice::from_raw_parts(transmute(&e.items), e.num_items as usize), + }), } } } @@ -563,62 +565,74 @@ pub struct MultiEvent<'a> { pub event: Event<'a>, } - impl<'a> MultiEvent<'a> { fn from_tdb_multi_event(e: *const traildb_sys::tdb_multi_event) -> Option { unsafe { match e.as_ref() { None => None, - Some(multi_event) => { - Some(MultiEvent { - event: Event::from_tdb_event(multi_event.event).unwrap(), - cursor_idx: multi_event.cursor_idx as usize, - }) - } + Some(multi_event) => Some(MultiEvent { + event: Event::from_tdb_event(multi_event.event).unwrap(), + cursor_idx: multi_event.cursor_idx as usize, + }), } } } } - pub struct EventFilter<'b> { - obj: &'b mut traildb_sys::tdb_event_filter + obj: &'b mut traildb_sys::tdb_event_filter, } impl<'b> EventFilter<'b> { pub fn new() -> EventFilter<'b> { let filter = unsafe { traildb_sys::tdb_event_filter_new() }; - EventFilter { obj: unsafe { transmute(filter) } } + EventFilter { + obj: unsafe { transmute(filter) }, + } } pub fn all() -> EventFilter<'b> { let filter = unsafe { traildb_sys::tdb_event_filter_new_match_all() }; - EventFilter { obj: unsafe { transmute(filter) } } + EventFilter { + obj: unsafe { transmute(filter) }, + } } pub fn none() -> EventFilter<'b> { let filter = unsafe { traildb_sys::tdb_event_filter_new_match_none() }; - EventFilter { obj: unsafe { transmute(filter) } } + EventFilter { + obj: unsafe { transmute(filter) }, + } } pub fn or(&mut self, item: Item) -> &mut EventFilter<'b> { - unsafe { traildb_sys::tdb_event_filter_add_term(self.obj, item.0, false as i32); }; + unsafe { + traildb_sys::tdb_event_filter_add_term(self.obj, item.0, false as i32); + }; self } pub fn or_not(&mut self, item: Item) -> &mut EventFilter<'b> { - unsafe { traildb_sys::tdb_event_filter_add_term(self.obj, item.0, true as i32); }; + unsafe { + traildb_sys::tdb_event_filter_add_term(self.obj, item.0, true as i32); + }; self } pub fn and(&mut self) -> &mut EventFilter<'b> { - let ret = wrap_tdb_err(unsafe { traildb_sys::tdb_event_filter_new_clause(self.obj) }, ()); + let ret = wrap_tdb_err( + unsafe { traildb_sys::tdb_event_filter_new_clause(self.obj) }, + (), + ); ret.expect("tdb_event_filter_new_clause failed"); self } pub fn time_range(&mut self, start: u64, end: u64) -> &mut EventFilter<'b> { - let ret = wrap_tdb_err(unsafe { traildb_sys::tdb_event_filter_add_time_range(self.obj, start, end) }, ()); + let ret = wrap_tdb_err( + unsafe { traildb_sys::tdb_event_filter_add_time_range(self.obj, start, end) }, + (), + ); ret.expect("tdb_event_filter_add_time_range failed"); self } @@ -628,25 +642,21 @@ impl<'b> EventFilter<'b> { } } - impl<'b> Drop for EventFilter<'b> { fn drop(&mut self) { unsafe { traildb_sys::tdb_event_filter_free(self.obj) }; } } - - - #[cfg(test)] mod tests { - extern crate uuid; extern crate tempdir; - use super::{Constructor, Db, Cursor, MultiCursor, MultiEvent, EventFilter}; + extern crate uuid; + use self::tempdir::TempDir; + use super::{Constructor, Cursor, Db, EventFilter, MultiCursor, MultiEvent}; use std::cell::RefCell; use std::collections::HashSet; use std::iter::FromIterator; - use self::tempdir::TempDir; #[test] #[no_mangle] @@ -678,7 +688,6 @@ mod tests { trail_cnt += 1; } - // finalize db (saves it to disk) assert!(cons.finalize().is_ok()); @@ -759,7 +768,6 @@ mod tests { assert!(cons.finalize().is_ok()); - let db = Db::open(&path).unwrap(); let cursors = vec![RefCell::new(db.cursor()), RefCell::new(db.cursor())]; @@ -772,16 +780,25 @@ mod tests { multi_cursor.reset(); let multi_events: Vec = multi_cursor.collect(); - assert_eq!(vec![10, 11, 12, 20, 21, 22], - multi_events.iter().map(|me| me.event.timestamp).collect::>()); - assert_eq!(HashSet::from_iter(vec![0, 0, 0, 1, 1, 1].into_iter()), - multi_events.iter().map(|me| me.cursor_idx).collect::>()); + assert_eq!( + vec![10, 11, 12, 20, 21, 22], + multi_events + .iter() + .map(|me| me.event.timestamp) + .collect::>() + ); + assert_eq!( + HashSet::from_iter(vec![0, 0, 0, 1, 1, 1].into_iter()), + multi_events + .iter() + .map(|me| me.cursor_idx) + .collect::>() + ); // TODO: Test dropping cursors, should not be allowed if multi // cursor is still around. } - #[test] fn filters() { let mut path = TempDir::new("traildb-tmp").unwrap().into_path(); @@ -812,7 +829,6 @@ mod tests { result } - let db = Db::open(&path).unwrap(); let fields = db.fields(); let field1 = fields.get("field1").unwrap(); @@ -837,7 +853,6 @@ mod tests { drop(f); - // field1=a OR field1=b with more ergonomic API let mut f = EventFilter::new(); f.or(db.get_item(*field1, "a").unwrap()) From a8a77eac7bcdeb2113f80a421a6a2f727ef0bc03 Mon Sep 17 00:00:00 2001 From: Jihyun Yu Date: Sat, 4 Apr 2020 01:40:09 +0900 Subject: [PATCH 2/3] fix unsound bug on MultiCursor --- src/lib.rs | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3e5b30c..74c6299 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,7 +1,6 @@ #[allow(non_camel_case_types, dead_code, non_snake_case, private_in_public)] extern crate traildb_sys; -use std::cell::RefCell; use std::ffi::CString; use std::fmt; use std::mem::{forget, transmute}; @@ -481,22 +480,19 @@ pub struct MultiCursor<'a> { impl<'a> MultiCursor<'a> { /// Open a cursor in each of the Dbs passed. If you want multiple /// cursors for the same db, include it multiple times. - pub fn new(cursors: &[RefCell>]) -> MultiCursor<'a> { - let mut ptrs: Vec<*const traildb_sys::tdb_cursor> = vec![]; - for refcell in cursors.iter() { - let cursor = refcell.borrow(); - let ptr: *const traildb_sys::tdb_cursor = cursor.obj; - ptrs.push(ptr); - } + pub fn new(cursors: &'a [Cursor<'a>]) -> MultiCursor<'a> { + use std::iter::FromIterator; - unsafe { - let ptr = traildb_sys::tdb_multi_cursor_new( - ptrs.as_slice().as_ptr() as *mut *mut traildb_sys::tdb_cursor, - ptrs.len() as u64, - ); - MultiCursor { - obj: transmute(ptr), - } + Self::from_iter(cursors) + } + + unsafe fn from_raw(ptrs: &[*const traildb_sys::tdb_cursor]) -> Self { + let ptr = traildb_sys::tdb_multi_cursor_new( + ptrs.as_ptr() as *mut *mut traildb_sys::tdb_cursor, + ptrs.len() as u64, + ); + MultiCursor { + obj: transmute(ptr), } } @@ -505,6 +501,17 @@ impl<'a> MultiCursor<'a> { } } +impl<'a> std::iter::FromIterator<&'a Cursor<'a>> for MultiCursor<'a> { + fn from_iter>>(iter: I) -> Self { + let mut ptrs: Vec<*const traildb_sys::tdb_cursor> = vec![]; + for cursor in iter.into_iter() { + let ptr: *const traildb_sys::tdb_cursor = cursor.obj; + ptrs.push(ptr); + } + unsafe { Self::from_raw(&ptrs) } + } +} + impl<'a> Drop for MultiCursor<'a> { fn drop(&mut self) { unsafe { traildb_sys::tdb_multi_cursor_free(self.obj) }; From 52ebcb49e8cc471be81af78a3ce11da8e526b015 Mon Sep 17 00:00:00 2001 From: Jihyun Yu Date: Sat, 4 Apr 2020 02:05:32 +0900 Subject: [PATCH 3/3] fix tests --- src/lib.rs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 74c6299..3a0c062 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -661,7 +661,6 @@ mod tests { extern crate uuid; use self::tempdir::TempDir; use super::{Constructor, Cursor, Db, EventFilter, MultiCursor, MultiEvent}; - use std::cell::RefCell; use std::collections::HashSet; use std::iter::FromIterator; @@ -777,13 +776,11 @@ mod tests { let db = Db::open(&path).unwrap(); - let cursors = vec![RefCell::new(db.cursor()), RefCell::new(db.cursor())]; - let mut multi_cursor = MultiCursor::new(&cursors); - let mut cursor1 = cursors[0].borrow_mut(); - let mut cursor2 = cursors[1].borrow_mut(); + let mut cursors = vec![db.cursor(), db.cursor()]; + assert!(cursors[0].get_trail(0).is_ok()); + assert!(cursors[1].get_trail(1).is_ok()); - assert!(cursor1.get_trail(0).is_ok()); - assert!(cursor2.get_trail(1).is_ok()); + let mut multi_cursor: MultiCursor = cursors.iter().collect(); multi_cursor.reset(); let multi_events: Vec = multi_cursor.collect();