Skip to content

Commit 072753b

Browse files
aw-query: Add preprocessing and refcounting
1 parent 2fc85f3 commit 072753b

File tree

5 files changed

+214
-43
lines changed

5 files changed

+214
-43
lines changed

aw-query/src/functions.rs

+20-20
Original file line numberDiff line numberDiff line change
@@ -7,97 +7,97 @@ pub type QueryFn =
77
fn(args: Vec<DataType>, env: &VarEnv, ds: &Datastore) -> Result<DataType, QueryError>;
88

99
pub fn fill_env(env: &mut VarEnv) {
10-
env.insert(
10+
env.declare_static(
1111
"print".to_string(),
1212
DataType::Function("print".to_string(), qfunctions::print),
1313
);
14-
env.insert(
14+
env.declare_static(
1515
"query_bucket".to_string(),
1616
DataType::Function("query_bucket".to_string(), qfunctions::query_bucket),
1717
);
18-
env.insert(
18+
env.declare_static(
1919
"query_bucket_names".to_string(),
2020
DataType::Function(
2121
"query_bucket_names".to_string(),
2222
qfunctions::query_bucket_names,
2323
),
2424
);
25-
env.insert(
25+
env.declare_static(
2626
"sort_by_duration".to_string(),
2727
DataType::Function("sort_by_duration".to_string(), qfunctions::sort_by_duration),
2828
);
29-
env.insert(
29+
env.declare_static(
3030
"sort_by_timestamp".to_string(),
3131
DataType::Function(
3232
"sort_by_timestamp".to_string(),
3333
qfunctions::sort_by_timestamp,
3434
),
3535
);
36-
env.insert(
36+
env.declare_static(
3737
"sum_durations".to_string(),
3838
DataType::Function("sum_durations".to_string(), qfunctions::sum_durations),
3939
);
40-
env.insert(
40+
env.declare_static(
4141
"limit_events".to_string(),
4242
DataType::Function("limit_events".to_string(), qfunctions::limit_events),
4343
);
44-
env.insert(
44+
env.declare_static(
4545
"contains".to_string(),
4646
DataType::Function("contains".to_string(), qfunctions::contains),
4747
);
48-
env.insert(
48+
env.declare_static(
4949
"flood".to_string(),
5050
DataType::Function("flood".to_string(), qfunctions::flood),
5151
);
52-
env.insert(
52+
env.declare_static(
5353
"find_bucket".to_string(),
5454
DataType::Function("find_bucket".to_string(), qfunctions::find_bucket),
5555
);
56-
env.insert(
56+
env.declare_static(
5757
"merge_events_by_keys".to_string(),
5858
DataType::Function(
5959
"merge_events_by_keys".to_string(),
6060
qfunctions::merge_events_by_keys,
6161
),
6262
);
63-
env.insert(
63+
env.declare_static(
6464
"chunk_events_by_key".to_string(),
6565
DataType::Function(
6666
"chunk_events_by_key".to_string(),
6767
qfunctions::chunk_events_by_key,
6868
),
6969
);
70-
env.insert(
70+
env.declare_static(
7171
"filter_keyvals".to_string(),
7272
DataType::Function("filter_keyvals".to_string(), qfunctions::filter_keyvals),
7373
);
74-
env.insert(
74+
env.declare_static(
7575
"filter_keyvals_regex".to_string(),
7676
DataType::Function(
7777
"filter_keyvals_regex".to_string(),
7878
qfunctions::filter_keyvals_regex,
7979
),
8080
);
81-
env.insert(
81+
env.declare_static(
8282
"filter_period_intersect".to_string(),
8383
DataType::Function(
8484
"filter_period_intersect".to_string(),
8585
qfunctions::filter_period_intersect,
8686
),
8787
);
88-
env.insert(
88+
env.declare_static(
8989
"split_url_events".to_string(),
9090
DataType::Function("split_url_events".to_string(), qfunctions::split_url_events),
9191
);
92-
env.insert(
92+
env.declare_static(
9393
"concat".to_string(),
9494
DataType::Function("concat".to_string(), qfunctions::concat),
9595
);
96-
env.insert(
96+
env.declare_static(
9797
"categorize".to_string(),
9898
DataType::Function("categorize".into(), qfunctions::categorize),
9999
);
100-
env.insert(
100+
env.declare_static(
101101
"tag".to_string(),
102102
DataType::Function("tag".into(), qfunctions::tag),
103103
);
@@ -521,7 +521,7 @@ mod validate {
521521
}
522522

523523
pub fn get_timeinterval(env: &VarEnv) -> Result<TimeInterval, QueryError> {
524-
let interval_str = match env.get("TIMEINTERVAL") {
524+
let interval_str = match env.deprecated_get("TIMEINTERVAL") {
525525
Some(data_ti) => match data_ti {
526526
DataType::String(ti_str) => ti_str,
527527
_ => {

aw-query/src/interpret.rs

+8-21
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,28 @@
11
use std::collections::HashMap;
22

3-
use crate::functions;
4-
53
use aw_datastore::Datastore;
6-
use aw_models::TimeInterval;
74

85
use crate::ast::*;
96
use crate::DataType;
107
use crate::QueryError;
11-
12-
pub type VarEnv = HashMap<String, DataType>;
13-
14-
fn init_env(ti: &TimeInterval) -> VarEnv {
15-
let mut env = HashMap::new();
16-
env.insert("TIMEINTERVAL".to_string(), DataType::String(ti.to_string()));
17-
functions::fill_env(&mut env);
18-
env
19-
}
8+
use crate::VarEnv;
209

2110
pub fn interpret_prog(
2211
p: Program,
23-
ti: &TimeInterval,
12+
env: &mut VarEnv,
2413
ds: &Datastore,
2514
) -> Result<DataType, QueryError> {
26-
let mut env = init_env(ti);
2715
for expr in p.stmts {
28-
interpret_expr(&mut env, ds, expr)?;
16+
interpret_expr(env, ds, expr)?;
2917
}
30-
match env.remove("RETURN") {
18+
match env.take("RETURN") {
3119
Some(ret) => Ok(ret),
3220
None => Err(QueryError::EmptyQuery()),
3321
}
3422
}
3523

3624
fn interpret_expr(
37-
env: &mut HashMap<String, DataType>,
25+
env: &mut VarEnv,
3826
ds: &Datastore,
3927
expr: Expr,
4028
) -> Result<DataType, QueryError> {
@@ -184,9 +172,8 @@ fn interpret_expr(
184172
env.insert(var, val);
185173
Ok(DataType::None())
186174
}
187-
// FIXME: avoid clone, it's slow
188-
Var(var) => match env.get(&var) {
189-
Some(v) => Ok(v.clone()),
175+
Var(var) => match env.take(&var) {
176+
Some(v) => Ok(v),
190177
None => Err(QueryError::VariableNotDefined(var.to_string())),
191178
},
192179
Bool(lit) => Ok(DataType::Bool(lit)),
@@ -215,7 +202,7 @@ fn interpret_expr(
215202
DataType::List(l) => l,
216203
_ => unreachable!(),
217204
};
218-
let var = match env.get(&fname[..]) {
205+
let var = match env.take(&fname[..]) {
219206
Some(v) => v,
220207
None => return Err(QueryError::VariableNotDefined(fname.clone())),
221208
};

aw-query/src/lib.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ mod lexer;
2121
unused_braces
2222
)]
2323
mod parser;
24+
mod varenv;
25+
mod preprocess;
2426

2527
pub use crate::datatype::DataType;
26-
pub use crate::interpret::VarEnv;
28+
pub use crate::varenv::VarEnv;
2729

2830
// TODO: add line numbers to errors
2931
// (works during lexing, but not during parsing I believe)
@@ -50,6 +52,14 @@ impl fmt::Display for QueryError {
5052
}
5153
}
5254

55+
fn init_env(ti: &TimeInterval) -> VarEnv {
56+
let mut env = VarEnv::new();
57+
env.declare_static("TIMEINTERVAL".to_string(), DataType::String(ti.to_string()));
58+
env.declare_static("RETURN".to_string(), DataType::None());
59+
functions::fill_env(&mut env);
60+
env
61+
}
62+
5363
pub fn query(code: &str, ti: &TimeInterval, ds: &Datastore) -> Result<DataType, QueryError> {
5464
let lexer = lexer::Lexer::new(code);
5565
let program = match parser::parse(lexer) {
@@ -60,5 +70,7 @@ pub fn query(code: &str, ti: &TimeInterval, ds: &Datastore) -> Result<DataType,
6070
return Err(QueryError::ParsingError(format!("{:?}", e)));
6171
}
6272
};
63-
interpret::interpret_prog(program, ti, ds)
73+
let mut env = init_env(ti);
74+
preprocess::preprocess_prog(&program, &mut env, ds)?;
75+
interpret::interpret_prog(program, &mut env, ds)
6476
}

aw-query/src/preprocess.rs

+87
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use aw_datastore::Datastore;
2+
3+
use crate::ast::*;
4+
use crate::DataType;
5+
use crate::QueryError;
6+
use crate::VarEnv;
7+
8+
pub fn preprocess_prog(
9+
p: &Program,
10+
env: &mut VarEnv,
11+
ds: &Datastore,
12+
) -> Result<(), QueryError> {
13+
for expr in &p.stmts {
14+
preprocess_expr(env, ds, expr)?;
15+
}
16+
Ok(())
17+
}
18+
19+
fn preprocess_expr(
20+
env: &mut VarEnv,
21+
ds: &Datastore,
22+
expr: &Expr,
23+
) -> Result<(), QueryError> {
24+
use crate::ast::Expr_::*;
25+
match &expr.node {
26+
Var(ref var) => env.add_ref(var)?,
27+
Add(ref a, ref b) => {
28+
preprocess_expr(env, ds, a)?;
29+
preprocess_expr(env, ds, b)?;
30+
}
31+
Sub(ref a, ref b) => {
32+
preprocess_expr(env, ds, a)?;
33+
preprocess_expr(env, ds, b)?;
34+
}
35+
Mul(ref a, ref b) => {
36+
preprocess_expr(env, ds, a)?;
37+
preprocess_expr(env, ds, b)?;
38+
}
39+
Div(ref a, ref b) => {
40+
preprocess_expr(env, ds, a)?;
41+
preprocess_expr(env, ds, b)?;
42+
}
43+
Mod(ref a, ref b) => {
44+
preprocess_expr(env, ds, a)?;
45+
preprocess_expr(env, ds, b)?;
46+
}
47+
Equal(ref a, ref b) => {
48+
preprocess_expr(env, ds, a)?;
49+
preprocess_expr(env, ds, b)?;
50+
}
51+
Assign(ref var, ref b) => {
52+
preprocess_expr(env, ds, b)?;
53+
env.declare(var.to_string());
54+
},
55+
Function(ref fname, ref args) => {
56+
env.add_ref(fname)?;
57+
preprocess_expr(env, ds, args)?;
58+
}
59+
If(ref ifs) => {
60+
for (cond, block) in ifs {
61+
// TODO: could be optimized?
62+
preprocess_expr(env, ds, cond)?;
63+
for expr in block {
64+
preprocess_expr(env, ds, expr)?;
65+
}
66+
}
67+
}
68+
List(list) => {
69+
for entry in list {
70+
preprocess_expr(env, ds, entry)?;
71+
}
72+
}
73+
Dict(d) => {
74+
for (key, val_uninterpreted) in d {
75+
preprocess_expr(env, ds, val_uninterpreted)?;
76+
}
77+
}
78+
Return(e) => {
79+
println!("return!");
80+
preprocess_expr(env, ds, e)?;
81+
},
82+
Bool(_lit) => (),
83+
Number(_lit) => (),
84+
String(_lit) => (),
85+
};
86+
Ok(())
87+
}

0 commit comments

Comments
 (0)