Eliminate empty changes and unused cache slots

This commit is contained in:
milner committed 2017-04-29 16:18:00 +00:00
1 parent 697f0a4d5c
commit e30acacfd6
6 files changed
+236 -12

No files matched your search

+80
View File
@@ -661,3 +661,83 @@ let aggregate_cases =
fail "cached matches the reference" (Printf.sprintf "ops=%d" (List.length ops)))
batches );
]
let simplified text = Simplify.simplify (plan text)
let simplify_cases =
[
( "a map in front of count is elided when the projection is total",
fun () ->
let plan = simplified "input rows : collection int\nquery q = rows |> map (fun r -> r * 2) |> count\n" in
check_equal_int "two nodes" 2 (List.length plan.Graph.pl_nodes);
check "source then count"
(match (List.nth plan.Graph.pl_nodes 1).Graph.n_kind with Graph.Count -> true | _ -> false) );
( "a map that can divide keeps its node but loses its cache",
fun () ->
let graph =
Graph.build
(Anf.program
(Specialize.program
(infer "input rows : collection int\nquery q = rows |> map (fun r -> 100 / r) |> count\n")))
in
let plan = Simplify.simplify graph in
check_equal_int "three nodes" 3 (List.length plan.Graph.pl_nodes);
let mapper = List.nth plan.Graph.pl_nodes 1 in
check "kept as a map" (match mapper.Graph.n_kind with Graph.Map _ -> true | _ -> false);
check "no cache" (mapper.Graph.n_cache = Graph.No_cache) );
( "a map feeding sum keeps its cache",
fun () ->
let plan = simplified "input rows : collection int\nquery q = rows |> map (fun r -> r * 2) |> sum\n" in
check_equal_int "three nodes" 3 (List.length plan.Graph.pl_nodes);
check "cache kept" ((List.nth plan.Graph.pl_nodes 1).Graph.n_cache = Graph.Cached_values) );
( "an identity map is elided",
fun () ->
let plan = simplified "input rows : collection int\nquery q = rows |> map (fun r -> r)\n" in
check_equal_int "one node" 1 (List.length plan.Graph.pl_nodes);
check "source only" (match (List.nth plan.Graph.pl_nodes 0).Graph.n_kind with Graph.Source -> true | _ -> false) );
( "a filter with a constant true predicate is elided",
fun () ->
let plan = simplified "input rows : collection int\nquery q = rows |> filter (fun r -> true) |> sum\n" in
check_equal_int "two nodes" 2 (List.length plan.Graph.pl_nodes);
check "a sum remains" (match (List.nth plan.Graph.pl_nodes 1).Graph.n_kind with Graph.Sum -> true | _ -> false) );
( "a filter is never elided when its predicate depends on the row",
fun () ->
let plan = simplified "input rows : collection int\nquery q = rows |> filter (fun r -> r > 0) |> count\n" in
check_equal_int "three nodes" 3 (List.length plan.Graph.pl_nodes);
check "filter kept" (match (List.nth plan.Graph.pl_nodes 1).Graph.n_kind with Graph.Filter _ -> true | _ -> false) );
( "the simplified plan still computes reference results",
fun () ->
let f =
build_fixture "input rows : collection int\nquery q = rows |> map (fun r -> 100 / r) |> sum\n"
[ (1, Value.VInt 5); (2, Value.VInt 4) ]
in
check_equal_string "initial" (Value.to_string (reference_result f f.fx_state))
(Value.to_string (Incremental.result f.fx_plan f.fx_state));
(match step f [ Change.OpInsert (3, Value.VInt 10) ] with
| Error message -> fail "insert" message
| Ok (applied, cached, _) ->
check_equal_string "applied" (Value.to_string (reference_result f f.fx_state))
(Value.to_string applied);
check_equal_string "cached" (Value.to_string (reference_result f f.fx_state))
(Value.to_string cached)) );
( "an elided map still reports division errors for new rows",
fun () ->
let f =
build_fixture "input rows : collection int\nquery q = rows |> map (fun r -> 100 / r) |> count\n"
[ (1, Value.VInt 5) ]
in
(match step f [ Change.OpInsert (2, Value.VInt 0) ] with
| Ok _ -> fail "division" "expected the elided map to still evaluate"
| Error message -> check "division by zero" (String.length message > 0)) );
( "decisions are reported per node",
fun () ->
let graph =
Graph.build
(Anf.program
(Specialize.program
(infer "input rows : collection int\nquery q = rows |> map (fun r -> r) |> count\n")))
in
let report = Simplify.decisions graph in
check "the identity map is elided" (String.length report > 0);
check "mentions a source" (Util.starts_with " keep node 0: source" report) );
]