From 2afe04b9aa9b2a7b23ed338448091a56b9d1cb7e Mon Sep 17 00:00:00 2001 From: Dirk Van Haerenborgh Date: Mon, 5 Nov 2018 19:54:28 +0100 Subject: update readme --- README.md | 61 +++++++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 14 deletions(-) (limited to 'README.md') diff --git a/README.md b/README.md index 2847e32..4719ee0 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,8 @@ extern crate notmuch; ```rust extern crate notmuch; +use notmuch::StreamingIterator; + fn main() { @@ -40,13 +42,8 @@ fn main() { let query = db.create_query(&"".to_string()).unwrap(); let mut threads = query.search_threads().unwrap(); - loop { - match threads.next() { - Some(thread) => { - println!("thread {:?} {:?}", thread.subject(), thread.authors()); - }, - None => { break } - } + while let Some(thread) = threads.next() { + println!("thread {:?} {:?}", thread.subject(), thread.authors()); } } @@ -59,13 +56,49 @@ thread locals, but I did not spot any locks. So, as far as I am concerned, it is not thread safe. So why do all structs implement ```Send``` and ```Sync```? Well, it _is_ safe to access pointers from different threads (as long as you know what you are doing :) ). -But, more importantly, all structs are strictly linked together with their -lifetime. The root of the tree is ```notmuch::Database```, which has a lifetime -that must outlive any related objects, for instance ```notmuch::Query```. The -```notmuch::Threads``` iterator that you can get from a ```notmuch::Query``` is -always outlived by the parent query. -This means that you can only use these structs accross thread bounds if you -figure out how to satisfy the lifetime requirements. +Up till now I haven't done a lot of multithreaded stuff with notmuch-rs. If you +feel this is too permissive, let me know. + +## Lifetime + +All structs are strictly linked together with their lifetime. The root of the +tree is ```Database```, which has a lifetime that must outlive any child +objects, for instance ```Query```. The ```Threads``` iterator that you can get +from a ```Query``` is always outlived by the parent query. ```Threads``` in its +turn must have a longer life than ```Thread```, which in turn must outlive +```Messages``` and so on. Each structure keeps a ```PhantomData``` marker of its +owner. + +Using this in an application poses significant difficulties in satisfying these +lifetime requirements. To alleviate this, ```notmuch-rs``` makes use of the +excellent [Supercow](https://crates.io/crates/supercow), so you don't have to +use crates like ```owningref``` or ```rental``` to get around this. + +This way, you get to choose your own container type, and even keep the parent +object alive so you don't have to juggle lifetimes. To use this, most types +are accompagnied with an ```*Ext``` trait, that accepts ```Rc```, ```Arc``` or +comparable. + +```rust + use std::sync::Arc; + use notmuch::{DatabaseExt}; + + let query = { + let dbr = Arc::new(db); + + ::create_query(dbr.clone(), &"".to_string()).unwrap() + }; + +``` + +## Iterators + +Since the lifetime of a ```Thread``` or a ```Message``` is dependent on the +```Threads``` and ```Messages``` iterator respectively, using the regular rust +```Iterator``` trait proved impossible. As such, ```notmuch-rs``` includes a +```StreamingIterator``` (and additional ```StreamingIteratorExt```) trait that +is used to iterate while satisfying the lifetime constraints. + ## Acknowledgements -- cgit v1.2.1