rethink Tuple type

main
Ziyang Hu 2 years ago
parent f5f0683548
commit b16c5db431

@ -22,7 +22,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -87,7 +86,7 @@ impl AlgoImpl for BetweennessCentrality {
for (i, s) in centrality.into_iter().enumerate() {
let node = indices[i].clone();
out.put(Tuple(vec![node, s.into()]), 0);
out.put(vec![node, s.into()], 0);
}
Ok(())
@ -138,10 +137,7 @@ impl AlgoImpl for ClosenessCentrality {
})
.collect::<Result<_>>()?;
for (idx, centrality) in res.into_iter().enumerate() {
out.put(
Tuple(vec![indices[idx].clone(), DataValue::from(centrality)]),
0,
);
out.put(vec![indices[idx].clone(), DataValue::from(centrality)], 0);
poison.check()?;
}
Ok(())

@ -61,12 +61,12 @@ impl AlgoImpl for ShortestPathAStar {
poison.clone(),
)?;
out.put(
Tuple(vec![
start.0[0].clone(),
goal.0[0].clone(),
vec![
start[0].clone(),
goal[0].clone(),
DataValue::from(cost),
DataValue::List(path),
]),
],
0,
);
}
@ -95,12 +95,12 @@ fn astar<'a>(
stores: &'a BTreeMap<MagicSymbol, InMemRelation>,
poison: Poison,
) -> Result<(f64, Vec<DataValue>)> {
let start_node = &starting.0[0];
let goal_node = &goal.0[0];
let start_node = &starting[0];
let goal_node = &goal[0];
let eval_heuristic = |node: &Tuple| -> Result<f64> {
let mut v = node.0.clone();
v.extend_from_slice(&goal.0);
let t = Tuple(v);
let mut v = node.clone();
v.extend_from_slice(&goal);
let t = v;
let cost_val = heuristic.eval(&t)?;
let cost = cost_val.get_float().ok_or_else(|| {
BadExprValueError(
@ -141,8 +141,8 @@ fn astar<'a>(
for edge in edges.prefix_iter(&node, tx, stores)? {
let edge = edge?;
let edge_dst = &edge.0[1];
let edge_cost = edge.0[2].get_float().ok_or_else(|| {
let edge_dst = &edge[1];
let edge_cost = edge[2].get_float().ok_or_else(|| {
BadExprValueError(
edge_dst.clone(),
edges.span(),

@ -15,7 +15,6 @@ use crate::algo::{AlgoImpl, NodeNotFoundError};
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -49,7 +48,7 @@ impl AlgoImpl for Bfs {
'outer: for node_tuple in starting_nodes.iter(tx, stores)? {
let node_tuple = node_tuple?;
let starting_node = &node_tuple.0[0];
let starting_node = &node_tuple[0];
if visited.contains(starting_node) {
continue;
}
@ -61,7 +60,7 @@ impl AlgoImpl for Bfs {
while let Some(candidate) = queue.pop_back() {
for edge in edges.prefix_iter(&candidate, tx, stores)? {
let edge = edge?;
let to_node = &edge.0[1];
let to_node = &edge[1];
if visited.contains(to_node) {
continue;
}
@ -70,7 +69,7 @@ impl AlgoImpl for Bfs {
backtrace.insert(to_node.clone(), candidate.clone());
let cand_tuple = if skip_query_nodes {
Tuple(vec![to_node.clone()])
vec![to_node.clone()]
} else {
nodes
.prefix_iter(to_node, tx, stores)?
@ -103,7 +102,7 @@ impl AlgoImpl for Bfs {
}
route.push(starting.clone());
route.reverse();
let tuple = Tuple(vec![starting, ending, DataValue::List(route)]);
let tuple = vec![starting, ending, DataValue::List(route)];
out.put(tuple, 0);
}
Ok(())

@ -16,7 +16,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol, WrongAlgoOptionError};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -37,7 +36,7 @@ impl AlgoImpl for Constant {
let data = algo.expr_option("data", None).unwrap();
let data = data.get_const().unwrap().get_list().unwrap();
for row in data {
let tuple = Tuple(row.get_list().unwrap().into());
let tuple = row.get_list().unwrap().into();
out.put(tuple, 0)
}
Ok(())

@ -22,7 +22,6 @@ use crate::data::program::{
};
use crate::data::relation::{ColType, NullableColType};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::{parse_type, SourceSpan};
use crate::runtime::db::Poison;
@ -91,16 +90,16 @@ impl AlgoImpl for CsvReader {
types.len()
};
let mut process_row = |row: StringRecord| -> Result<()> {
let mut out_tuple = Tuple(Vec::with_capacity(out_tuple_size));
let mut out_tuple = Vec::with_capacity(out_tuple_size);
if prepend_index {
counter += 1;
out_tuple.0.push(DataValue::from(counter));
out_tuple.push(DataValue::from(counter));
}
for (i, typ) in types.iter().enumerate() {
match row.get(i) {
None => {
if typ.nullable {
out_tuple.0.push(DataValue::Null)
out_tuple.push(DataValue::Null)
} else {
bail!(
"encountered null value when processing CSV when non-null required"
@ -110,8 +109,8 @@ impl AlgoImpl for CsvReader {
Some(s) => {
let dv = DataValue::Str(SmartString::from(s));
match &typ.coltype {
ColType::Any | ColType::String => out_tuple.0.push(dv),
ColType::Uuid => out_tuple.0.push(match op_to_uuid(&[dv]) {
ColType::Any | ColType::String => out_tuple.push(dv),
ColType::Uuid => out_tuple.push(match op_to_uuid(&[dv]) {
Ok(uuid) => uuid,
Err(err) => {
if typ.nullable {
@ -121,7 +120,7 @@ impl AlgoImpl for CsvReader {
}
}
}),
ColType::Float => out_tuple.0.push(match op_to_float(&[dv]) {
ColType::Float => out_tuple.push(match op_to_float(&[dv]) {
Ok(data) => data,
Err(err) => {
if typ.nullable {
@ -136,12 +135,12 @@ impl AlgoImpl for CsvReader {
match f.get_int() {
None => {
if typ.nullable {
out_tuple.0.push(DataValue::Null)
out_tuple.push(DataValue::Null)
} else {
bail!("cannot convert {} to type {}", s, typ)
}
}
Some(i) => out_tuple.0.push(DataValue::from(i)),
Some(i) => out_tuple.push(DataValue::from(i)),
};
}
_ => bail!("cannot convert {} to type {}", s, typ),

@ -15,7 +15,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -39,12 +38,12 @@ impl AlgoImpl for DegreeCentrality {
let mut counter: BTreeMap<DataValue, (usize, usize, usize)> = BTreeMap::new();
for tuple in it {
let tuple = tuple?;
let from = tuple.0[0].clone();
let from = tuple[0].clone();
let (from_total, from_out, _) = counter.entry(from).or_default();
*from_total += 1;
*from_out += 1;
let to = tuple.0[1].clone();
let to = tuple[1].clone();
let (to_total, _, to_in) = counter.entry(to).or_default();
*to_total += 1;
*to_in += 1;
@ -53,7 +52,7 @@ impl AlgoImpl for DegreeCentrality {
if let Ok(nodes) = algo.relation(1) {
for tuple in nodes.iter(tx, stores)? {
let tuple = tuple?;
let id = &tuple.0[0];
let id = &tuple[0];
if !counter.contains_key(id) {
counter.insert(id.clone(), (0, 0, 0));
}
@ -61,12 +60,12 @@ impl AlgoImpl for DegreeCentrality {
}
}
for (k, (total_d, out_d, in_d)) in counter.into_iter() {
let tuple = Tuple(vec![
let tuple = vec![
k,
DataValue::from(total_d as i64),
DataValue::from(out_d as i64),
DataValue::from(in_d as i64),
]);
];
out.put(tuple, 0);
poison.check()?;
}

@ -15,7 +15,6 @@ use crate::algo::{AlgoImpl, NodeNotFoundError};
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -49,7 +48,7 @@ impl AlgoImpl for Dfs {
'outer: for node_tuple in starting_nodes.iter(tx, stores)? {
let node_tuple = node_tuple?;
let starting_node = &node_tuple.0[0];
let starting_node = &node_tuple[0];
if visited.contains(starting_node) {
continue;
}
@ -63,7 +62,7 @@ impl AlgoImpl for Dfs {
}
let cand_tuple = if skip_query_nodes {
Tuple(vec![candidate.clone()])
vec![candidate.clone()]
} else {
nodes
.prefix_iter(&candidate, tx, stores)?
@ -85,7 +84,7 @@ impl AlgoImpl for Dfs {
for edge in edges.prefix_iter(&candidate, tx, stores)? {
let edge = edge?;
let to_node = &edge.0[1];
let to_node = &edge[1];
if visited.contains(to_node) {
continue;
}
@ -105,7 +104,7 @@ impl AlgoImpl for Dfs {
}
route.push(starting.clone());
route.reverse();
let tuple = Tuple(vec![starting, ending, DataValue::List(route)]);
let tuple = vec![starting, ending, DataValue::List(route)];
out.put(tuple, 0);
poison.check()?;
}

@ -25,7 +25,6 @@ use crate::data::expr::Expr;
use crate::data::json::JsonValue;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -86,7 +85,7 @@ impl AlgoImpl for JsonReader {
};
ret.push(val);
}
out.put(Tuple(ret), 0);
out.put(ret, 0);
Ok(())
};
match url.strip_prefix("file://") {

@ -19,7 +19,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -46,11 +45,11 @@ impl AlgoImpl for MinimumSpanningForestKruskal {
let msp = kruskal(&graph, poison)?;
for (src, dst, cost) in msp {
out.put(
Tuple(vec![
vec![
indices[src].clone(),
indices[dst].clone(),
DataValue::from(cost),
]),
],
0,
);
}

@ -17,7 +17,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -43,7 +42,7 @@ impl AlgoImpl for LabelPropagation {
let labels = label_propagation(&graph, max_iter, poison)?;
for (idx, label) in labels.into_iter().enumerate() {
let node = indices[idx].clone();
out.put(Tuple(vec![DataValue::from(label as i64), node]), 0);
out.put(vec![DataValue::from(label as i64), node], 0);
}
Ok(())
}

@ -17,7 +17,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -66,7 +65,7 @@ impl AlgoImpl for CommunityDetectionLouvain {
if let Some(l) = keep_depth {
labels.truncate(l);
}
out.put(Tuple(vec![DataValue::List(labels), node]), 0);
out.put(vec![DataValue::List(labels), node], 0);
}
Ok(())

@ -51,7 +51,7 @@ use crate::algo::yen::KShortestPathYen;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicAlgoRuleArg, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::{Tuple, TupleIter};
use crate::data::tuple::TupleIter;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -263,7 +263,7 @@ impl MagicAlgoRuleArg {
let mut has_neg_edge = false;
for tuple in self.iter(tx, stores)? {
let mut tuple = tuple?.0.into_iter();
let mut tuple = tuple?.into_iter();
let from = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?;
let to = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?;
let weight = match tuple.next() {
@ -342,7 +342,7 @@ impl MagicAlgoRuleArg {
let mut inv_indices: BTreeMap<DataValue, usize> = Default::default();
for tuple in self.iter(tx, stores)? {
let mut tuple = tuple?.0.into_iter();
let mut tuple = tuple?.into_iter();
let from = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?;
let to = tuple.next().ok_or_else(|| NotAnEdgeError(self.span()))?;
let from_idx = if let Some(idx) = inv_indices.get(&from) {
@ -382,12 +382,12 @@ impl MagicAlgoRuleArg {
let store = stores.get(name).ok_or_else(|| {
RuleNotFoundError(name.symbol().to_string(), name.symbol().span)
})?;
let t = Tuple(vec![prefix.clone()]);
let t = vec![prefix.clone()];
Box::new(store.scan_prefix(&t))
}
MagicAlgoRuleArg::Stored { name, .. } => {
let relation = tx.get_relation(name, false)?;
let t = Tuple(vec![prefix.clone()]);
let t = vec![prefix.clone()];
Box::new(relation.scan_prefix(tx, &t))
}
})

@ -21,7 +21,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -66,7 +65,7 @@ impl AlgoImpl for PageRank {
for (idx, score) in ranks.iter().enumerate() {
out.put(
Tuple(vec![indices[idx].clone(), DataValue::from(*score as f64)]),
vec![indices[idx].clone(), DataValue::from(*score as f64)],
0,
);
}

@ -20,7 +20,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -55,7 +54,7 @@ impl AlgoImpl for MinimumSpanningTreePrim {
EmptyStarting(rel.span())
})??;
let dv = &tuple.0[0];
let dv = &tuple[0];
*inv_indices.get(dv).ok_or_else(|| {
#[derive(Debug, Error, Diagnostic)]
#[error("The requested starting node {0:?} is not found")]
@ -69,11 +68,11 @@ impl AlgoImpl for MinimumSpanningTreePrim {
let msp = prim(&graph, starting, poison)?;
for (src, dst, cost) in msp {
out.put(
Tuple(vec![
vec![
indices[src].clone(),
indices[dst].clone(),
DataValue::from(cost),
]),
],
0,
);
}

@ -18,7 +18,6 @@ use crate::algo::{AlgoImpl, BadExprValueError, NodeNotFoundError};
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -55,7 +54,7 @@ impl AlgoImpl for RandomWalk {
let mut rng = thread_rng();
for start_node in starting.iter(tx, stores)? {
let start_node = start_node?;
let start_node_key = &start_node.0[0];
let start_node_key = &start_node[0];
let starting_tuple = nodes
.prefix_iter(start_node_key, tx, stores)?
.next()
@ -68,7 +67,7 @@ impl AlgoImpl for RandomWalk {
let mut current_tuple = starting_tuple.clone();
let mut path = vec![start_node_key.clone()];
for _ in 0..steps {
let cur_node_key = &current_tuple.0[0];
let cur_node_key = &current_tuple[0];
let candidate_steps: Vec<_> =
edges.prefix_iter(cur_node_key, tx, stores)?.try_collect()?;
if candidate_steps.is_empty() {
@ -79,7 +78,7 @@ impl AlgoImpl for RandomWalk {
.iter()
.map(|t| -> Result<f64> {
let mut cand = current_tuple.clone();
cand.0.extend_from_slice(&t.0);
cand.extend_from_slice(&t);
Ok(match weight_expr.eval(&cand)? {
DataValue::Num(n) => {
let f = n.get_float();
@ -108,7 +107,7 @@ impl AlgoImpl for RandomWalk {
} else {
candidate_steps.choose(&mut rng).unwrap()
};
let next_node = &next_step.0[1];
let next_node = &next_step[1];
path.push(next_node.clone());
current_tuple = nodes
.prefix_iter(next_node, tx, stores)?
@ -120,11 +119,11 @@ impl AlgoImpl for RandomWalk {
poison.check()?;
}
out.put(
Tuple(vec![
vec![
DataValue::from(counter),
start_node_key.clone(),
DataValue::List(path),
]),
],
0,
);
}

@ -17,7 +17,6 @@ use crate::data::expr::Expr;
use crate::data::functions::OP_LIST;
use crate::data::program::{MagicAlgoApply, MagicSymbol, WrongAlgoOptionError};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -117,7 +116,7 @@ impl AlgoImpl for ReorderSort {
}
let mut out_t = vec![DataValue::from(if break_ties { count } else { rank } as i64)];
out_t.extend_from_slice(&val[0..val.len() - 1]);
out.put(Tuple(out_t), 0);
out.put(out_t, 0);
poison.check()?;
}
Ok(())

@ -23,7 +23,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -53,7 +52,7 @@ impl AlgoImpl for ShortestPathDijkstra {
let mut starting_nodes = BTreeSet::new();
for tuple in starting.iter(tx, stores)? {
let tuple = tuple?;
let node = &tuple.0[0];
let node = &tuple[0];
if let Some(idx) = inv_indices.get(node) {
starting_nodes.insert(*idx);
}
@ -64,7 +63,7 @@ impl AlgoImpl for ShortestPathDijkstra {
let mut tn = BTreeSet::new();
for tuple in t.iter(tx, stores)? {
let tuple = tuple?;
let node = &tuple.0[0];
let node = &tuple[0];
if let Some(idx) = inv_indices.get(node) {
tn.insert(*idx);
}
@ -98,7 +97,7 @@ impl AlgoImpl for ShortestPathDijkstra {
DataValue::from(cost),
DataValue::List(path.into_iter().map(|u| indices[u].clone()).collect_vec()),
];
out.put(Tuple(t), 0)
out.put(t, 0)
}
}
} else {
@ -145,7 +144,7 @@ impl AlgoImpl for ShortestPathDijkstra {
DataValue::from(cost),
DataValue::List(path.into_iter().map(|u| indices[u].clone()).collect_vec()),
];
out.put(Tuple(t), 0)
out.put(t, 0)
}
}
}

@ -55,7 +55,7 @@ impl AlgoImpl for StronglyConnectedComponent {
for (grp_id, cc) in tarjan.iter().enumerate() {
for idx in cc {
let val = indices.get(*idx).unwrap();
let tuple = Tuple(vec![val.clone(), DataValue::from(grp_id as i64)]);
let tuple = vec![val.clone(), DataValue::from(grp_id as i64)];
out.put(tuple, 0);
}
}
@ -65,10 +65,10 @@ impl AlgoImpl for StronglyConnectedComponent {
if let Ok(nodes) = algo.relation(1) {
for tuple in nodes.iter(tx, stores)? {
let tuple = tuple?;
let node = tuple.0.into_iter().next().unwrap();
let node = tuple.into_iter().next().unwrap();
if !inv_indices.contains_key(&node) {
inv_indices.insert(node.clone(), usize::MAX);
let tuple = Tuple(vec![node, DataValue::from(counter)]);
let tuple = vec![node, DataValue::from(counter)];
out.put(tuple, 0);
counter += 1;
}

@ -15,7 +15,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -41,7 +40,7 @@ impl AlgoImpl for TopSort {
for (idx, val_id) in sorted.iter().enumerate() {
let val = indices.get(*val_id).unwrap();
let tuple = Tuple(vec![DataValue::from(idx as i64), val.clone()]);
let tuple = vec![DataValue::from(idx as i64), val.clone()];
out.put(tuple, 0);
}

@ -17,7 +17,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -42,12 +41,12 @@ impl AlgoImpl for ClusteringCoefficients {
let coefficients = clustering_coefficients(&graph, poison)?;
for (idx, (cc, n_triangles, degree)) in coefficients.into_iter().enumerate() {
out.put(
Tuple(vec![
vec![
indices[idx].clone(),
DataValue::from(cc),
DataValue::from(n_triangles as i64),
DataValue::from(degree as i64),
]),
],
0,
);
}

@ -19,7 +19,6 @@ use crate::algo::AlgoImpl;
use crate::data::expr::Expr;
use crate::data::program::{MagicAlgoApply, MagicSymbol};
use crate::data::symb::Symbol;
use crate::data::tuple::Tuple;
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::db::Poison;
@ -49,7 +48,7 @@ impl AlgoImpl for KShortestPathYen {
let mut starting_nodes = BTreeSet::new();
for tuple in starting.iter(tx, stores)? {
let tuple = tuple?;
let node = &tuple.0[0];
let node = &tuple[0];
if let Some(idx) = inv_indices.get(node) {
starting_nodes.insert(*idx);
}
@ -57,7 +56,7 @@ impl AlgoImpl for KShortestPathYen {
let mut termination_nodes = BTreeSet::new();
for tuple in termination.iter(tx, stores)? {
let tuple = tuple?;
let node = &tuple.0[0];
let node = &tuple[0];
if let Some(idx) = inv_indices.get(node) {
termination_nodes.insert(*idx);
}
@ -76,7 +75,7 @@ impl AlgoImpl for KShortestPathYen {
path.into_iter().map(|u| indices[u].clone()).collect_vec(),
),
];
out.put(Tuple(t), 0)
out.put(t, 0)
}
}
}
@ -107,7 +106,7 @@ impl AlgoImpl for KShortestPathYen {
DataValue::from(cost),
DataValue::List(path.into_iter().map(|u| indices[u].clone()).collect_vec()),
];
out.put(Tuple(t), 0)
out.put(t, 0)
}
}
}

@ -253,7 +253,7 @@ impl Expr {
all_evaluated = all_evaluated && matches!(arg, Expr::Const { .. });
}
if all_evaluated {
let result = self.eval(&Tuple(vec![]))?;
let result = self.eval(&vec![])?;
mem::swap(self, &mut Expr::Const { val: result, span });
}
// nested not's can accumulate during conversion to normal form
@ -328,10 +328,9 @@ impl Expr {
struct TupleTooShortError(String, usize, usize, #[label] SourceSpan);
Ok(bindings
.0
.get(*i)
.ok_or_else(|| {
TupleTooShortError(var.name.to_string(), *i, bindings.0.len(), var.span)
TupleTooShortError(var.name.to_string(), *i, bindings.len(), var.span)
})?
.clone())
}

@ -6,37 +6,33 @@
* You can obtain one at https://mozilla.org/MPL/2.0/.
*/
use std::fmt::{Debug, Formatter};
use miette::Result;
use crate::data::memcmp::MemCmpEncoder;
use crate::data::value::DataValue;
use crate::runtime::relation::RelationId;
#[derive(Clone, Ord, PartialOrd, Eq, PartialEq, Default)]
pub struct Tuple(pub(crate) Vec<DataValue>);
impl Debug for Tuple {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
f.debug_list().entries(&self.0).finish()
}
}
pub type Tuple = Vec<DataValue>;
pub(crate) type TupleIter<'a> = Box<dyn Iterator<Item = Result<Tuple>> + 'a>;
impl Tuple {
pub(crate) fn encode_as_key(&self, prefix: RelationId) -> Vec<u8> {
let len = self.0.len();
pub(crate) trait TupleT {
fn encode_as_key(&self, prefix: RelationId) -> Vec<u8>;
fn decode_from_key(key: &[u8]) -> Self;
}
impl TupleT for Tuple {
fn encode_as_key(&self, prefix: RelationId) -> Vec<u8> {
let len = self.len();
let mut ret = Vec::with_capacity(4 + 4 * len + 10 * len);
let prefix_bytes = prefix.0.to_be_bytes();
ret.extend(prefix_bytes);
for val in self.0.iter() {
for val in self.iter() {
ret.encode_datavalue(val);
}
ret
}
pub(crate) fn decode_from_key(key: &[u8]) -> Self {
fn decode_from_key(key: &[u8]) -> Self {
let mut remaining = &key[ENCODED_KEY_MIN_LEN..];
let mut ret = vec![];
while !remaining.is_empty() {
@ -44,7 +40,7 @@ impl Tuple {
ret.push(val);
remaining = next;
}
Tuple(ret)
ret
}
}
pub(crate) const ENCODED_KEY_MIN_LEN: usize = 8;

@ -87,7 +87,7 @@ impl PartialOrd for RegexWrapper {
#[derive(
Clone, PartialEq, Eq, PartialOrd, Ord, serde_derive::Deserialize, serde_derive::Serialize, Hash,
)]
pub(crate) enum DataValue {
pub enum DataValue {
Null,
Bool(bool),
Num(Num),

@ -232,7 +232,7 @@ impl<'a> SessionTx<'a> {
.filter_map(|(i, a)| if a.is_none() { Some(i) } else { None })
.collect_vec();
let extract_keys = |t: &Tuple| -> Vec<DataValue> {
keys_indices.iter().map(|i| t.0[*i].clone()).collect_vec()
keys_indices.iter().map(|i| t[*i].clone()).collect_vec()
};
let val_indices_and_aggrs = rule
@ -261,7 +261,7 @@ impl<'a> SessionTx<'a> {
.normal_op
.as_mut()
.unwrap()
.set(&item.0[*tuple_idx])?;
.set(&item[*tuple_idx])?;
}
}
Entry::Vacant(ent) => {
@ -269,7 +269,7 @@ impl<'a> SessionTx<'a> {
for (i, (aggr, params)) in &val_indices_and_aggrs {
let mut cur_aggr = aggr.clone();
cur_aggr.normal_init(params)?;
cur_aggr.normal_op.as_mut().unwrap().set(&item.0[*i])?;
cur_aggr.normal_op.as_mut().unwrap().set(&item[*i])?;
aggr_ops.push(cur_aggr)
}
ent.insert(aggr_ops);
@ -305,7 +305,7 @@ impl<'a> SessionTx<'a> {
}
})
.try_collect()?;
let tuple = Tuple(tuple_data);
let tuple = tuple_data;
if should_check_limit {
if !store.exists(&tuple, 0) {
store.put_with_skip(tuple, limiter.should_skip_next());

@ -71,19 +71,17 @@ struct EntityIdExpected(DataValue, #[label] SourceSpan);
fn eliminate_from_tuple(mut ret: Tuple, eliminate_indices: &BTreeSet<usize>) -> Tuple {
if !eliminate_indices.is_empty() {
ret = Tuple(
ret.0
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec(),
);
ret = ret
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec();
}
ret
}
@ -137,9 +135,9 @@ impl UnificationRA {
})?;
let mut coll = vec![];
for result in result_list {
let mut ret = tuple.0.clone();
let mut ret = tuple.clone();
ret.push(result.clone());
let ret = Tuple(ret);
let ret = ret;
let ret = eliminate_from_tuple(ret, &eliminate_indices);
coll.push(ret);
}
@ -154,9 +152,9 @@ impl UnificationRA {
.iter(tx, epoch, use_delta)?
.map_ok(move |tuple| -> Result<Tuple> {
let result = self.expr.eval(&tuple)?;
let mut ret = tuple.0;
let mut ret = tuple;
ret.push(result);
let ret = Tuple(ret);
let ret = ret;
let ret = eliminate_from_tuple(ret, &eliminate_indices);
Ok(ret)
})
@ -575,12 +573,12 @@ impl ReorderRA {
.collect_vec();
Ok(Box::new(self.relation.iter(tx, epoch, use_delta)?.map_ok(
move |tuple| {
let old = tuple.0;
let old = tuple;
let new = reorder_indices
.iter()
.map(|i| old[*i].clone())
.collect_vec();
Tuple(new)
new
},
)))
}
@ -638,11 +636,11 @@ impl InlineFixedRA {
.map(|v| data[v].clone())
.collect_vec();
Box::new(left_iter.filter_map_ok(move |tuple| {
let left_join_values = left_join_indices.iter().map(|v| &tuple.0[*v]).collect_vec();
let left_join_values = left_join_indices.iter().map(|v| &tuple[*v]).collect_vec();
if left_join_values.into_iter().eq(right_join_values.iter()) {
let mut ret = tuple.0;
let mut ret = tuple;
ret.extend_from_slice(&data);
let ret = Tuple(ret);
let ret = ret;
let ret = eliminate_from_tuple(ret, &eliminate_indices);
Some(ret)
} else {
@ -666,13 +664,13 @@ impl InlineFixedRA {
left_iter
.filter_map_ok(move |tuple| {
let left_join_values =
left_join_indices.iter().map(|v| &tuple.0[*v]).collect_vec();
left_join_indices.iter().map(|v| &tuple[*v]).collect_vec();
right_mapping.get(&left_join_values).map(|v| {
v.iter()
.map(|right_values| {
let mut left_data = tuple.0.clone();
let mut left_data = tuple.clone();
left_data.extend_from_slice(right_values);
Tuple(left_data)
left_data
})
.collect_vec()
})
@ -775,12 +773,10 @@ impl StoredRA {
let mut skip_range_check = false;
let it = left_iter
.map_ok(move |tuple| {
let prefix = Tuple(
left_to_prefix_indices
.iter()
.map(|i| tuple.0[*i].clone())
.collect_vec(),
);
let prefix = left_to_prefix_indices
.iter()
.map(|i| tuple[*i].clone())
.collect_vec();
let filters = self.filters.clone();
if !skip_range_check && !self.filters.is_empty() {
@ -802,9 +798,9 @@ impl StoredRA {
return Ok(None);
}
}
let mut ret = tuple.0.clone();
ret.extend(found.0);
Ok(Some(Tuple(ret)))
let mut ret = tuple.clone();
ret.extend(found);
Ok(Some(ret))
})
.filter_map(swap_option_result),
);
@ -821,9 +817,9 @@ impl StoredRA {
return Ok(None);
}
}
let mut ret = tuple.0.clone();
ret.extend(found.0);
Ok(Some(Tuple(ret)))
let mut ret = tuple.clone();
ret.extend(found);
Ok(Some(ret))
})
.filter_map(swap_option_result),
)
@ -859,19 +855,17 @@ impl StoredRA {
Ok(Box::new(
left_iter
.map_ok(move |tuple| -> Result<Option<Tuple>> {
let prefix = Tuple(
left_to_prefix_indices
.iter()
.map(|i| tuple.0[*i].clone())
.collect_vec(),
);
let prefix = left_to_prefix_indices
.iter()
.map(|i| tuple[*i].clone())
.collect_vec();
'outer: for found in self.storage.scan_prefix(tx, &prefix) {
let found = found?;
for (left_idx, right_idx) in
left_join_indices.iter().zip(right_join_indices.iter())
{
if tuple.0[*left_idx] != found.0[*right_idx] {
if tuple[*left_idx] != found[*right_idx] {
continue 'outer;
}
}
@ -879,20 +873,17 @@ impl StoredRA {
}
Ok(Some(if !eliminate_indices.is_empty() {
Tuple(
tuple
.0
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec(),
)
tuple
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec()
} else {
tuple
}))
@ -907,7 +898,7 @@ impl StoredRA {
let tuple = tuple?;
let to_join: Box<[DataValue]> = right_join_indices
.iter()
.map(|i| tuple.0[*i].clone())
.map(|i| tuple[*i].clone())
.collect();
right_join_vals.insert(to_join);
}
@ -916,27 +907,24 @@ impl StoredRA {
.map_ok(move |tuple| -> Result<Option<Tuple>> {
let left_join_vals: Box<[DataValue]> = left_join_indices
.iter()
.map(|i| tuple.0[*i].clone())
.map(|i| tuple[*i].clone())
.collect();
if right_join_vals.contains(&left_join_vals) {
return Ok(None);
}
Ok(Some(if !eliminate_indices.is_empty() {
Tuple(
tuple
.0
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec(),
)
tuple
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec()
} else {
tuple
}))
@ -1033,19 +1021,17 @@ impl InMemRelationRA {
Ok(Box::new(
left_iter
.map_ok(move |tuple| -> Result<Option<Tuple>> {
let prefix = Tuple(
left_to_prefix_indices
.iter()
.map(|i| tuple.0[*i].clone())
.collect_vec(),
);
let prefix = left_to_prefix_indices
.iter()
.map(|i| tuple[*i].clone())
.collect_vec();
'outer: for found in self.storage.scan_prefix(&prefix) {
let found = found?;
for (left_idx, right_idx) in
left_join_indices.iter().zip(right_join_indices.iter())
{
if tuple.0[*left_idx] != found.0[*right_idx] {
if tuple[*left_idx] != found[*right_idx] {
continue 'outer;
}
}
@ -1053,20 +1039,17 @@ impl InMemRelationRA {
}
Ok(Some(if !eliminate_indices.is_empty() {
Tuple(
tuple
.0
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec(),
)
tuple
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec()
} else {
tuple
}))
@ -1080,7 +1063,7 @@ impl InMemRelationRA {
let tuple = tuple?;
let to_join: Box<[DataValue]> = right_join_indices
.iter()
.map(|i| tuple.0[*i].clone())
.map(|i| tuple[*i].clone())
.collect();
right_join_vals.insert(to_join);
}
@ -1090,26 +1073,23 @@ impl InMemRelationRA {
.map_ok(move |tuple| -> Result<Option<Tuple>> {
let left_join_vals: Box<[DataValue]> = left_join_indices
.iter()
.map(|i| tuple.0[*i].clone())
.map(|i| tuple[*i].clone())
.collect();
if right_join_vals.contains(&left_join_vals) {
return Ok(None);
}
Ok(Some(if !eliminate_indices.is_empty() {
Tuple(
tuple
.0
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec(),
)
tuple
.into_iter()
.enumerate()
.filter_map(|(i, v)| {
if eliminate_indices.contains(&i) {
None
} else {
Some(v)
}
})
.collect_vec()
} else {
tuple
}))
@ -1149,12 +1129,10 @@ impl InMemRelationRA {
let mut skip_range_check = false;
let it = left_iter
.map_ok(move |tuple| {
let prefix = Tuple(
left_to_prefix_indices
.iter()
.map(|i| tuple.0[*i].clone())
.collect_vec(),
);
let prefix = left_to_prefix_indices
.iter()
.map(|i| tuple[*i].clone())
.collect_vec();
let filters = self.filters.clone();
@ -1179,9 +1157,9 @@ impl InMemRelationRA {
return Ok(None);
}
}
let mut ret = tuple.0.clone();
ret.extend(found.0);
Ok(Some(Tuple(ret)))
let mut ret = tuple.clone();
ret.extend(found);
Ok(Some(ret))
})
.filter_map(swap_option_result),
);
@ -1198,9 +1176,9 @@ impl InMemRelationRA {
return Ok(None);
}
}
let mut ret = tuple.0.clone();
ret.extend(found.0);
Ok(Some(Tuple(ret)))
let mut ret = tuple.clone();
ret.extend(found);
Ok(Some(ret))
})
.filter_map(swap_option_result),
)
@ -1325,7 +1303,7 @@ impl RelAlgebra {
use_delta: &BTreeSet<StoredRelationId>,
) -> Result<TupleIter<'a>> {
match self {
RelAlgebra::Fixed(f) => Ok(Box::new(f.data.iter().map(|t| Ok(Tuple(t.clone()))))),
RelAlgebra::Fixed(f) => Ok(Box::new(f.data.iter().map(|t| Ok(t.clone())))),
RelAlgebra::InMem(r) => r.iter(epoch, use_delta),
RelAlgebra::Stored(v) => v.iter(tx),
RelAlgebra::Join(j) => j.iter(tx, epoch, use_delta),
@ -1640,9 +1618,9 @@ impl InnerJoin {
Ok(tuple) => {
let stored_tuple = right_store_indices
.iter()
.map(|i| tuple.0[*i].clone())
.map(|i| tuple[*i].clone())
.collect_vec();
cache.insert(Tuple(stored_tuple));
cache.insert(stored_tuple);
}
Err(e) => return Err(e),
}
@ -1687,7 +1665,7 @@ impl<'a> CachedMaterializedIterator<'a> {
None
} else {
let ret = &self.materialized[self.right_idx];
if ret.0.starts_with(&self.prefix.0) {
if ret.starts_with(&self.prefix) {
self.right_idx += 1;
Some(ret)
} else {
@ -1703,7 +1681,7 @@ impl<'a> CachedMaterializedIterator<'a> {
let data = data.clone();
let mut ret = self.left_cache.clone();
for i in &self.right_invert_indices {
ret.0.push(data.0[*i].clone());
ret.push(data[*i].clone());
}
let tuple = eliminate_from_tuple(ret, &self.eliminate_indices);
return Ok(Some(tuple));
@ -1736,12 +1714,10 @@ fn build_mat_range_iter(
left_join_indices: &[usize],
left_tuple: &Tuple,
) -> (Tuple, usize) {
let prefix = Tuple(
left_join_indices
.iter()
.map(|i| left_tuple.0[*i].clone())
.collect_vec(),
);
let prefix = left_join_indices
.iter()
.map(|i| left_tuple[*i].clone())
.collect_vec();
let idx = match mat.binary_search(&prefix) {
Ok(i) => i,
Err(i) => i,

@ -34,7 +34,7 @@ impl<'a> SessionTx<'a> {
let mut all_data: Vec<_> = original.scan_all().try_collect()?;
all_data.sort_by(|a, b| {
for (idx, dir) in &idx_sorters {
match a.0[*idx].cmp(&b.0[*idx]) {
match a[*idx].cmp(&b[*idx]) {
Ordering::Equal => {}
o => {
return match dir {

@ -111,12 +111,10 @@ impl<'a> SessionTx<'a> {
for tuple in res_iter {
let tuple = tuple?;
let extracted = Tuple(
key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?,
);
let extracted = key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?;
let key = relation_store.encode_key_for_store(&extracted, *span)?;
if has_triggers {
if let Some(existing) = self.tx.get(&key, false)? {
@ -125,13 +123,13 @@ impl<'a> SessionTx<'a> {
let mut remaining = &existing[ENCODED_KEY_MIN_LEN..];
while !remaining.is_empty() {
let (val, nxt) = DataValue::decode_from_key(remaining);
tup.0.push(val);
tup.push(val);
remaining = nxt;
}
}
old_tuples.push(DataValue::List(tup.0));
old_tuples.push(DataValue::List(tup));
}
new_tuples.push(DataValue::List(extracted.0.clone()));
new_tuples.push(DataValue::List(extracted.clone()));
}
self.tx.del(&key)?;
}
@ -197,12 +195,10 @@ impl<'a> SessionTx<'a> {
for tuple in res_iter {
let tuple = tuple?;
let extracted = Tuple(
key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?,
);
let extracted = key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?;
let key = relation_store.encode_key_for_store(&extracted, *span)?;
let val = relation_store.encode_val_for_store(&extracted, *span)?;
@ -212,7 +208,7 @@ impl<'a> SessionTx<'a> {
None => {
bail!(TransactAssertionFailure {
relation: relation_store.name.to_string(),
key: extracted.0,
key: extracted,
notice: "key does not exist in database".to_string()
})
}
@ -220,7 +216,7 @@ impl<'a> SessionTx<'a> {
if &v as &[u8] != &val as &[u8] {
bail!(TransactAssertionFailure {
relation: relation_store.name.to_string(),
key: extracted.0,
key: extracted,
notice: "key exists in database, but value does not match"
.to_string()
})
@ -247,17 +243,15 @@ impl<'a> SessionTx<'a> {
for tuple in res_iter {
let tuple = tuple?;
let extracted = Tuple(
key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?,
);
let extracted = key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?;
let key = relation_store.encode_key_for_store(&extracted, *span)?;
if self.tx.exists(&key, true)? {
bail!(TransactAssertionFailure {
relation: relation_store.name.to_string(),
key: extracted.0,
key: extracted,
notice: "key exists in database".to_string()
})
}
@ -294,12 +288,10 @@ impl<'a> SessionTx<'a> {
for tuple in res_iter {
let tuple = tuple?;
let extracted = Tuple(
key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?,
);
let extracted = key_extractors
.iter()
.map(|ex| ex.extract_data(&tuple))
.try_collect()?;
let key = relation_store.encode_key_for_store(&extracted, *span)?;
let val = relation_store.encode_val_for_store(&extracted, *span)?;
@ -310,13 +302,13 @@ impl<'a> SessionTx<'a> {
let mut remaining = &existing[ENCODED_KEY_MIN_LEN..];
while !remaining.is_empty() {
let (val, nxt) = DataValue::decode_from_key(remaining);
tup.0.push(val);
tup.push(val);
remaining = nxt;
}
old_tuples.push(DataValue::List(tup.0));
old_tuples.push(DataValue::List(tup));
}
new_tuples.push(DataValue::List(extracted.0));
new_tuples.push(DataValue::List(extracted));
}
self.tx.put(&key, &val)?;
@ -378,10 +370,10 @@ impl DataExtractor {
Ok(match self {
DataExtractor::DefaultExtractor(expr, typ) => typ
.coerce(expr.clone().eval_to_const()?)
.wrap_err_with(|| format!("when processing tuple {:?}", tuple.0))?,
.wrap_err_with(|| format!("when processing tuple {:?}", tuple))?,
DataExtractor::IndexExtractor(i, typ) => typ
.coerce(tuple.0[*i].clone())
.wrap_err_with(|| format!("when processing tuple {:?}", tuple.0))?,
.coerce(tuple[*i].clone())
.wrap_err_with(|| format!("when processing tuple {:?}", tuple))?,
})
}
}

@ -24,7 +24,7 @@ use thiserror::Error;
use crate::data::json::JsonValue;
use crate::data::program::{InputProgram, QueryAssertion, RelationOp};
use crate::data::relation::ColumnDef;
use crate::data::tuple::Tuple;
use crate::data::tuple::{Tuple, TupleT};
use crate::data::value::{DataValue, LARGEST_UTF_CHAR};
use crate::decode_tuple_from_kv;
use crate::parse::sys::SysOp;
@ -180,7 +180,7 @@ impl<'s, S: Storage<'s>> Db<S> {
for data in tx.tx.range_scan(&start, &end) {
let (k, v) = data?;
let tuple = decode_tuple_from_kv(&k, &v);
let row = tuple.0.into_iter().map(JsonValue::from).collect_vec();
let row = tuple.into_iter().map(JsonValue::from).collect_vec();
rows.push(row);
}
let headers = cols.iter().map(|col| col.to_string()).collect_vec();
@ -277,7 +277,7 @@ impl<'s, S: Storage<'s>> Db<S> {
col.typing.coerce(DataValue::from(v))
})
.try_collect()?;
let k_store = handle.encode_key_for_store(&Tuple(keys), Default::default())?;
let k_store = handle.encode_key_for_store(&keys, Default::default())?;
if is_delete {
tx.tx.del(&k_store)?;
} else {
@ -291,7 +291,7 @@ impl<'s, S: Storage<'s>> Db<S> {
})
.try_collect()?;
let v_store =
handle.encode_val_only_for_store(&Tuple(vals), Default::default())?;
handle.encode_val_only_for_store(&vals, Default::default())?;
tx.tx.put(&k_store, &v_store)?;
}
}
@ -390,7 +390,7 @@ impl<'s, S: Storage<'s>> Db<S> {
fn compact_relation(&'s self) -> Result<()> {
let l = Tuple::default().encode_as_key(RelationId(0));
let u = Tuple(vec![DataValue::Bot]).encode_as_key(RelationId(u64::MAX));
let u = vec![DataValue::Bot].encode_as_key(RelationId(u64::MAX));
self.db.range_compact(&l, &u)?;
Ok(())
}
@ -891,7 +891,7 @@ impl<'s, S: Storage<'s>> Db<S> {
} else {
let rows: Vec<Vec<JsonValue>> = sorted_iter
.map_ok(|tuple| -> Vec<JsonValue> {
tuple.0.into_iter().map(JsonValue::from).collect()
tuple.into_iter().map(JsonValue::from).collect()
})
.try_collect()?;
let headers: Vec<String> = match input_program.get_entry_out_head() {
@ -937,7 +937,7 @@ impl<'s, S: Storage<'s>> Db<S> {
} else {
let rows: Vec<Vec<JsonValue>> = scan
.map_ok(|tuple| -> Vec<JsonValue> {
tuple.0.into_iter().map(JsonValue::from).collect()
tuple.into_iter().map(JsonValue::from).collect()
})
.try_collect()?;
@ -1005,10 +1005,10 @@ impl<'s, S: Storage<'s>> Db<S> {
}
fn list_relations(&'s self) -> Result<NamedRows> {
let lower =
Tuple(vec![DataValue::Str(SmartString::from(""))]).encode_as_key(RelationId::SYSTEM);
let upper = Tuple(vec![DataValue::Str(SmartString::from(String::from(
vec![DataValue::Str(SmartString::from(""))].encode_as_key(RelationId::SYSTEM);
let upper = vec![DataValue::Str(SmartString::from(String::from(
LARGEST_UTF_CHAR,
)))])
)))]
.encode_as_key(RelationId::SYSTEM);
let tx = self.db.transact(false)?;
let mut rows: Vec<Vec<JsonValue>> = vec![];
@ -1073,10 +1073,10 @@ impl Poison {
}
#[cfg(not(feature = "nothread"))]
pub(crate) fn set_timeout(&self, secs: f64) -> Result<()> {
let pill = self.0.clone();
let pill = self.clone();
thread::spawn(move || {
thread::sleep(Duration::from_micros((secs * 1000000.) as u64));
pill.store(true, Ordering::Relaxed);
pill.0.store(true, Ordering::Relaxed);
});
Ok(())
}

@ -10,7 +10,6 @@ use std::borrow::Borrow;
use std::cell::RefCell;
use std::collections::BTreeMap;
use std::fmt::{Debug, Formatter};
use std::ops::Bound::Included;
use std::rc::Rc;
use std::sync::atomic::{AtomicU32, Ordering};
use std::sync::Arc;
@ -88,20 +87,18 @@ impl InMemRelation {
let zero_target: &RefCell<BTreeMap<_, _>> = zero_map.borrow();
let mut zero_target = zero_target.borrow_mut();
let key = Tuple(
aggrs
.iter()
.enumerate()
.map(|(i, ma)| {
if ma.is_none() {
tuple.0[i].clone()
} else {
// placeholder for meet aggregation
DataValue::Guard
}
})
.collect_vec(),
);
let key = aggrs
.iter()
.enumerate()
.map(|(i, ma)| {
if ma.is_none() {
tuple[i].clone()
} else {
// placeholder for meet aggregation
DataValue::Guard
}
})
.collect_vec();
let prev_aggr = zero_target.get_mut(&key);
if let Some(prev_aggr) = prev_aggr {
@ -109,7 +106,7 @@ impl InMemRelation {
for (i, aggr) in aggrs.iter_mut().enumerate() {
if let Some((aggr_op, _aggr_args)) = aggr {
let op = aggr_op.meet_op.as_mut().unwrap();
changed |= op.update(&mut prev_aggr.0[i], &tuple.0[i])?;
changed |= op.update(&mut prev_aggr[i], &tuple[i])?;
}
}
if changed && epoch != 0 {
@ -121,20 +118,18 @@ impl InMemRelation {
}
Ok(changed)
} else {
let tuple_to_store = Tuple(
aggrs
.iter()
.enumerate()
.map(|(i, aggr)| -> Result<DataValue> {
if aggr.is_some() {
Ok(tuple.0[i].clone())
} else {
// placeholder for key part
Ok(DataValue::Guard)
}
})
.try_collect()?,
);
let tuple_to_store: Tuple = aggrs
.iter()
.enumerate()
.map(|(i, aggr)| -> Result<DataValue> {
if aggr.is_some() {
Ok(tuple[i].clone())
} else {
// placeholder for key part
Ok(DataValue::Guard)
}
})
.try_collect()?;
zero_target.insert(key.clone(), tuple_to_store.clone());
if epoch != 0 {
let epoch_maps = mem_db.borrow();
@ -163,7 +158,7 @@ impl InMemRelation {
if should_skip {
// put guard, so that when iterating results, those with guards are ignored
epoch_map.insert(tuple, Tuple(vec![DataValue::Guard]));
epoch_map.insert(tuple, vec![DataValue::Guard]);
} else {
epoch_map.insert(tuple, Tuple::default());
}
@ -191,22 +186,22 @@ impl InMemRelation {
let collected = epoch_map
.iter()
.map(|(k, v)| {
if v.0.is_empty() {
if v.is_empty() {
k.clone()
} else {
let combined =
k.0.iter()
.zip(v.0.iter())
.map(|(kel, vel)| {
// merge meet aggregation kv
if matches!(kel, DataValue::Guard) {
vel.clone()
} else {
kel.clone()
}
})
.collect_vec();
Tuple(combined)
let combined = k
.iter()
.zip(v.iter())
.map(|(kel, vel)| {
// merge meet aggregation kv
if matches!(kel, DataValue::Guard) {
vel.clone()
} else {
kel.clone()
}
})
.collect_vec();
combined
}
})
.collect_vec();
@ -225,25 +220,25 @@ impl InMemRelation {
let collected = epoch_map
.iter()
.filter_map(|(k, v)| {
if v.0.is_empty() {
if v.is_empty() {
Some(k.clone())
} else if v.0.last() == Some(&DataValue::Guard) {
} else if v.last() == Some(&DataValue::Guard) {
// ignore since we are using :offset
None
} else {
let combined =
k.0.iter()
.zip(v.0.iter())
.map(|(kel, vel)| {
// merge kv parts of meet aggr
if matches!(kel, DataValue::Guard) {
vel.clone()
} else {
kel.clone()
}
})
.collect_vec();
Some(Tuple(combined))
let combined = k
.iter()
.zip(v.iter())
.map(|(kel, vel)| {
// merge kv parts of meet aggr
if matches!(kel, DataValue::Guard) {
vel.clone()
} else {
kel.clone()
}
})
.collect_vec();
Some(combined)
}
})
.collect_vec();
@ -257,9 +252,9 @@ impl InMemRelation {
prefix: &Tuple,
epoch: u32,
) -> impl Iterator<Item = Result<Tuple>> {
let mut upper = prefix.0.clone();
let mut upper = prefix.clone();
upper.push(DataValue::Bot);
let upper = Tuple(upper);
let upper = upper;
let mem_db: &RefCell<_> = self.mem_db.borrow();
let epoch_maps = mem_db.borrow();
let epoch_map = epoch_maps.get(epoch as usize).unwrap();
@ -267,24 +262,24 @@ impl InMemRelation {
let epoch_map = epoch_map.borrow();
let collected = epoch_map
.range((Included(prefix), Included(&upper)))
.range(prefix.clone()..=upper)
.map(|(k, v)| {
if v.0.is_empty() {
if v.is_empty() {
k.clone()
} else {
let combined =
k.0.iter()
.zip(v.0.iter())
.map(|(kel, vel)| {
// merge kv parts of meet aggr
if matches!(kel, DataValue::Guard) {
vel.clone()
} else {
kel.clone()
}
})
.collect_vec();
Tuple(combined)
let combined = k
.iter()
.zip(v.iter())
.map(|(kel, vel)| {
// merge kv parts of meet aggr
if matches!(kel, DataValue::Guard) {
vel.clone()
} else {
kel.clone()
}
})
.collect_vec();
combined
}
})
.collect_vec();
@ -298,9 +293,9 @@ impl InMemRelation {
epoch: u32,
) -> impl Iterator<Item = Result<Tuple>> {
let mut prefix_bound = prefix.clone();
prefix_bound.0.extend_from_slice(lower);
prefix_bound.extend_from_slice(lower);
let mut upper_bound = prefix.clone();
upper_bound.0.extend_from_slice(upper);
upper_bound.extend_from_slice(upper);
let mem_db: &RefCell<_> = self.mem_db.borrow();
let epoch_maps = mem_db.borrow();
@ -309,11 +304,11 @@ impl InMemRelation {
let epoch_map = epoch_map.borrow();
let res = epoch_map
.range((Included(&prefix_bound), Included(&upper_bound)))
.range(prefix_bound..=upper_bound)
.map(|(k, _v)| k.clone())
.collect_vec();
res.into_iter().map(Ok)
}
}
// meet put
// meet put

@ -19,7 +19,7 @@ use thiserror::Error;
use crate::data::memcmp::MemCmpEncoder;
use crate::data::relation::StoredRelationMetadata;
use crate::data::symb::Symbol;
use crate::data::tuple::{Tuple, ENCODED_KEY_MIN_LEN};
use crate::data::tuple::{Tuple, TupleT, ENCODED_KEY_MIN_LEN};
use crate::data::value::DataValue;
use crate::parse::SourceSpan;
use crate::runtime::transact::SessionTx;
@ -130,16 +130,16 @@ impl RelationHandle {
pub(crate) fn encode_key_for_store(&self, tuple: &Tuple, span: SourceSpan) -> Result<Vec<u8>> {
let len = self.metadata.keys.len();
ensure!(
tuple.0.len() >= len,
tuple.len() >= len,
StoredRelArityMismatch {
name: self.name.to_string(),
expect_arity: self.arity(),
actual_arity: tuple.0.len(),
actual_arity: tuple.len(),
span
}
);
let mut ret = self.encode_key_prefix(len);
for val in &tuple.0[0..len] {
for val in &tuple[0..len] {
ret.encode_datavalue(val);
}
Ok(ret)
@ -148,7 +148,7 @@ impl RelationHandle {
let start = self.metadata.keys.len();
let len = self.metadata.non_keys.len();
let mut ret = self.encode_key_prefix(len);
tuple.0[start..]
tuple[start..]
.serialize(&mut Serializer::new(&mut ret))
.unwrap();
Ok(ret)
@ -158,8 +158,8 @@ impl RelationHandle {
tuple: &Tuple,
_span: SourceSpan,
) -> Result<Vec<u8>> {
let mut ret = self.encode_key_prefix(tuple.0.len());
tuple.0.serialize(&mut Serializer::new(&mut ret)).unwrap();
let mut ret = self.encode_key_prefix(tuple.len());
tuple.serialize(&mut Serializer::new(&mut ret)).unwrap();
Ok(ret)
}
pub(crate) fn ensure_compatible(&self, inp: &InputRelationHandle) -> Result<()> {
@ -230,12 +230,12 @@ impl RelationHandle {
tx: &'a SessionTx<'_>,
prefix: &Tuple,
) -> impl Iterator<Item = Result<Tuple>> + 'a {
let mut lower = prefix.0.clone();
let mut lower = prefix.clone();
lower.truncate(self.metadata.keys.len());
let mut upper = lower.clone();
upper.push(DataValue::Bot);
let prefix_encoded = Tuple(lower).encode_as_key(self.id);
let upper_encoded = Tuple(upper).encode_as_key(self.id);
let prefix_encoded = lower.encode_as_key(self.id);
let upper_encoded = upper.encode_as_key(self.id);
// RelationIterator::new(tx, &prefix_encoded, &upper_encoded)
tx.tx.range_scan_tuple(&prefix_encoded, &upper_encoded)
}
@ -247,10 +247,10 @@ impl RelationHandle {
upper: &[DataValue],
) -> impl Iterator<Item = Result<Tuple>> + 'a {
let mut lower_t = prefix.clone();
lower_t.0.extend_from_slice(lower);
lower_t.extend_from_slice(lower);
let mut upper_t = prefix.clone();
upper_t.0.extend_from_slice(upper);
upper_t.0.push(DataValue::Bot);
upper_t.extend_from_slice(upper);
upper_t.push(DataValue::Bot);
let lower_encoded = lower_t.encode_as_key(self.id);
let upper_encoded = upper_t.encode_as_key(self.id);
tx.tx.range_scan_tuple(&lower_encoded, &upper_encoded)
@ -264,7 +264,7 @@ pub fn decode_tuple_from_kv(key: &[u8], val: &[u8]) -> Tuple {
let mut tup = Tuple::decode_from_key(key);
if !val.is_empty() {
let vals: Vec<DataValue> = rmp_serde::from_slice(&val[ENCODED_KEY_MIN_LEN..]).unwrap();
tup.0.extend(vals);
tup.extend(vals);
}
tup
}
@ -277,7 +277,7 @@ struct RelNameConflictError(String);
impl<'a> SessionTx<'a> {
pub(crate) fn relation_exists(&self, name: &str) -> Result<bool> {
let key = DataValue::Str(SmartString::from(name));
let encoded = Tuple(vec![key]).encode_as_key(RelationId::SYSTEM);
let encoded = vec![key].encode_as_key(RelationId::SYSTEM);
self.tx.exists(&encoded, false)
}
pub(crate) fn set_relation_triggers(
@ -300,7 +300,7 @@ impl<'a> SessionTx<'a> {
original.replace_triggers = replaces;
let name_key =
Tuple(vec![DataValue::Str(original.name.clone())]).encode_as_key(RelationId::SYSTEM);
vec![DataValue::Str(original.name.clone())].encode_as_key(RelationId::SYSTEM);
let mut meta_val = vec![];
original
@ -315,7 +315,7 @@ impl<'a> SessionTx<'a> {
input_meta: InputRelationHandle,
) -> Result<RelationHandle> {
let key = DataValue::Str(input_meta.name.name.clone());
let encoded = Tuple(vec![key]).encode_as_key(RelationId::SYSTEM);
let encoded = vec![key].encode_as_key(RelationId::SYSTEM);
if self.tx.exists(&encoded, true)? {
bail!(RelNameConflictError(input_meta.name.to_string()))
@ -334,15 +334,14 @@ impl<'a> SessionTx<'a> {
};
self.tx.put(&encoded, &meta.id.raw_encode())?;
let name_key =
Tuple(vec![DataValue::Str(meta.name.clone())]).encode_as_key(RelationId::SYSTEM);
let name_key = vec![DataValue::Str(meta.name.clone())].encode_as_key(RelationId::SYSTEM);
let mut meta_val = vec![];
meta.serialize(&mut Serializer::new(&mut meta_val).with_struct_map())
.unwrap();
self.tx.put(&name_key, &meta_val)?;
let tuple = Tuple(vec![DataValue::Null]);
let tuple = vec![DataValue::Null];
let t_encoded = tuple.encode_as_key(RelationId::SYSTEM);
self.tx.put(&t_encoded, &meta.id.raw_encode())?;
Ok(meta)
@ -354,7 +353,7 @@ impl<'a> SessionTx<'a> {
struct StoredRelationNotFoundError(String);
let key = DataValue::Str(SmartString::from(name as &str));
let encoded = Tuple(vec![key]).encode_as_key(RelationId::SYSTEM);
let encoded = vec![key].encode_as_key(RelationId::SYSTEM);
let found = self
.tx
@ -373,7 +372,7 @@ impl<'a> SessionTx<'a> {
))
}
let key = DataValue::Str(SmartString::from(name as &str));
let encoded = Tuple(vec![key]).encode_as_key(RelationId::SYSTEM);
let encoded = vec![key].encode_as_key(RelationId::SYSTEM);
self.tx.del(&encoded)?;
let lower_bound = Tuple::default().encode_as_key(store.id);
let upper_bound = Tuple::default().encode_as_key(store.id.next());
@ -383,8 +382,7 @@ impl<'a> SessionTx<'a> {
let mut meta = self.get_relation(&rel, true)?;
meta.access_level = level;
let name_key =
Tuple(vec![DataValue::Str(meta.name.clone())]).encode_as_key(RelationId::SYSTEM);
let name_key = vec![DataValue::Str(meta.name.clone())].encode_as_key(RelationId::SYSTEM);
let mut meta_val = vec![];
meta.serialize(&mut Serializer::new(&mut meta_val).with_struct_map())
@ -395,14 +393,14 @@ impl<'a> SessionTx<'a> {
}
pub(crate) fn rename_relation(&mut self, old: Symbol, new: Symbol) -> Result<()> {
let new_key = DataValue::Str(new.name.clone());
let new_encoded = Tuple(vec![new_key]).encode_as_key(RelationId::SYSTEM);
let new_encoded = vec![new_key].encode_as_key(RelationId::SYSTEM);
if self.tx.exists(&new_encoded, true)? {
bail!(RelNameConflictError(new.name.to_string()))
};
let old_key = DataValue::Str(old.name.clone());
let old_encoded = Tuple(vec![old_key]).encode_as_key(RelationId::SYSTEM);
let old_encoded = vec![old_key].encode_as_key(RelationId::SYSTEM);
let mut rel = self.get_relation(&old, true)?;
if rel.access_level < AccessLevel::Normal {
@ -434,6 +432,7 @@ pub(crate) struct InsufficientAccessLevel(
#[cfg(test)]
mod tests {
use serde_json::json;
use crate::new_cozo_mem;
#[test]
@ -443,7 +442,8 @@ mod tests {
.unwrap();
db.run_script(":create friends.rev {to: Int, fr: Int}", Default::default())
.unwrap();
db.run_script(r#"
db.run_script(
r#"
::set_triggers friends
on put {
@ -456,7 +456,10 @@ mod tests {
:rm friends.rev{ to, fr }
}
"#, Default::default()).unwrap();
"#,
Default::default(),
)
.unwrap();
db.run_script(
r"?[fr, to] <- [[1,2]] :put friends {fr, to}",
Default::default(),

@ -12,7 +12,7 @@ use std::sync::Arc;
use miette::Result;
use crate::data::program::MagicSymbol;
use crate::data::tuple::Tuple;
use crate::data::tuple::TupleT;
use crate::data::value::DataValue;
use crate::runtime::in_mem::{InMemRelation, StoredRelationId};
use crate::runtime::relation::RelationId;
@ -34,7 +34,7 @@ impl<'a> SessionTx<'a> {
}
pub(crate) fn load_last_relation_store_id(&self) -> Result<RelationId> {
let tuple = Tuple(vec![DataValue::Null]);
let tuple = vec![DataValue::Null];
let t_encoded = tuple.encode_as_key(RelationId::SYSTEM);
let found = self.tx.get(&t_encoded, false)?;
Ok(match found {

Loading…
Cancel
Save