Update mod.rs

Add parser for key/value pairs to be indexed. Measurement and field are represented as _m and _f respectively.
pull/24376/head
Paul Dix 2019-12-20 13:05:59 -05:00
parent 5d80d5e100
commit 7f2f4eaceb
1 changed files with 82 additions and 0 deletions

View File

@ -1,4 +1,6 @@
use std::str::Chars;
use std::{error, fmt};
use std::fs::read;
#[derive(Debug, PartialEq, Clone)]
pub struct Point {
@ -7,6 +9,74 @@ pub struct Point {
pub value: i64,
}
impl Point {
// TODO: handle escapes in the line protocol for , = and \t
/// index_pairs parses the series key into key value pairs for insertion into the index. In
/// cases where this series is already in the database, this parse step can be skipped entirely.
/// The measurement is represented as a _m key and field as _f.
pub fn index_pairs(&self) -> Result<Vec<Pair>, ParseError> {
let mut chars = self.series.chars();
let mut pairs = vec![];
let mut key = "_m".to_string();
let mut value = String::with_capacity(250);
let mut reading_key = false;
while let Some(ch) = chars.next() {
match ch {
',' => {
reading_key = true;
pairs.push(Pair{key, value});
key = String::with_capacity(250);
value = String::with_capacity(250);
},
'=' => {
reading_key = false;
},
'\t' => {
reading_key = false;
pairs.push(Pair{key, value});
key = "_f".to_string();
value = String::with_capacity(250);
},
_ => {
if reading_key {
key.push(ch);
} else {
value.push(ch);
}
}
}
}
pairs.push(Pair{key, value});
Ok(pairs)
}
}
#[derive(Debug, PartialEq)]
pub struct Pair {
pub key: String,
pub value: String,
}
#[derive(Debug, Clone)]
pub struct ParseError {
description: String,
}
impl fmt::Display for ParseError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.description)
}
}
impl error::Error for ParseError {
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
// Generic error, underlying cause isn't tracked.
None
}
}
// TODO: have parse return an error for invalid inputs
pub fn parse(input: &str) -> Vec<Point> {
let mut points = Vec::with_capacity(10000);
@ -98,4 +168,16 @@ mod test {
assert_eq!(vals[1].time, 1234);
assert_eq!(vals[1].value, 5);
}
#[test]
fn index_pairs() {
let p = Point{series: "cpu,host=A,region=west\tusage_system".to_string(), value: 0, time: 0};
let pairs = p.index_pairs().unwrap();
assert_eq!(pairs, vec![
Pair{key: "_m".to_string(), value: "cpu".to_string()},
Pair{key: "host".to_string(), value: "A".to_string()},
Pair{key: "region".to_string(), value: "west".to_string()},
Pair{key: "_f".to_string(), value: "usage_system".to_string()},
]);
}
}