Reduces the number of allocations during NTriples parsing

pull/10/head
Tpt 7 years ago
parent dda9c8e5b7
commit d92e5466f5
  1. 38
      src/rio/ntriples/mod.rs
  2. 4
      src/rio/ntriples/ntriples_grammar.rustpeg

@ -11,15 +11,37 @@ use std::io::BufRead;
use std::io::BufReader;
use std::io::Read;
pub fn read_ntriples<'a, R: Read + 'a>(source: R) -> impl Iterator<Item = RioResult<Triple>> {
//TODO: use read_lines to avoid allocations
let lines = BufReader::new(source).lines();
let mut bnodes_map: BTreeMap<String, BlankNode> = BTreeMap::default();
lines.flat_map(move |line| match line {
Ok(line) => match grammar::triple(line.as_str(), &mut bnodes_map) {
Ok(triple) => Some(Ok(triple?)),
struct NTriplesIterator<R: Read> {
buffer: String,
reader: BufReader<R>,
bnodes_map: BTreeMap<String, BlankNode>,
}
impl<R: Read> Iterator for NTriplesIterator<R> {
type Item = RioResult<Triple>;
fn next(&mut self) -> Option<RioResult<Triple>> {
match self.reader.read_line(&mut self.buffer) {
Ok(line_count) => if line_count == 0 {
None
} else {
let result = grammar::triple(&self.buffer, &mut self.bnodes_map);
self.buffer.clear();
match result {
Ok(Some(triple)) => Some(Ok(triple)),
Ok(None) => self.next(),
Err(error) => Some(Err(RioError::new(error))),
}
},
Err(error) => Some(Err(error.into())),
})
}
}
}
pub fn read_ntriples<'a, R: Read + 'a>(source: R) -> impl Iterator<Item = RioResult<Triple>> {
NTriplesIterator {
buffer: String::default(),
reader: BufReader::new(source),
bnodes_map: BTreeMap::default(),
}
}

@ -11,8 +11,8 @@ use std::collections::BTreeMap;
//[2]
#[pub]
triple -> Option<Triple> =
_ s:subject _ p:predicate _ o:object _ "." _ comment? { Some(Triple::new(s, p, o)) } /
_ comment? { None }
_ s:subject _ p:predicate _ o:object _ "." _ comment? EOL? { Some(Triple::new(s, p, o)) } /
_ comment? EOL? { None }
//[3]
subject -> NamedOrBlankNode =

Loading…
Cancel
Save