summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Ziv Scully <ziv@mit.edu>2015-11-19 18:13:01 -0500
committerGravatar Ziv Scully <ziv@mit.edu>2015-11-19 18:13:01 -0500
commitff19a9c86b380918f50e294848be06f29b2ba1dd (patch)
treeb085c4af87bc8dbb854754793c6968f3a6b3c395
parent94b1dbce1ae20ded6b2e8cc519f56ac9e3b39b24 (diff)
More work on heuristics.
-rw-r--r--src/sqlcache.sml41
1 files changed, 33 insertions, 8 deletions
diff --git a/src/sqlcache.sml b/src/sqlcache.sml
index 312ee217..b2c8504b 100644
--- a/src/sqlcache.sml
+++ b/src/sqlcache.sml
@@ -93,11 +93,13 @@ val cacheRef = ref LruCache.cache
fun setCache c = cacheRef := c
fun getCache () = !cacheRef
-datatype heuristic = Always | Never | NoPureAll | NoPureOne | NoCombo
+datatype heuristic = SmartEq (* | SmartSub *) | Always | Never | NoPureAll | NoPureOne | NoCombo
val heuristicRef = ref Always
fun setHeuristic h = heuristicRef := (case h of
- "always" => Always
+ "smarteq" => SmartEq
+ (* | "smartsub" => SmartSub *)
+ | "always" => Always
| "never" => Never
| "nopureall" => NoPureAll
| "nopureone" => NoPureOne
@@ -613,13 +615,13 @@ end = struct
val union = op@
+ fun addToSqlArgsMap ((q, subst), acc) =
+ IM.foldl (fn (arg, acc) => AM.insert (acc, arg, ())) acc subst
+
fun sqlArgsMap (qs : t) =
let
val args =
- List.foldl (fn ((q, subst), acc) =>
- IM.foldl (fn (arg, acc) => AM.insert (acc, arg, ())) acc subst)
- AM.empty
- qs
+ List.foldl addToSqlArgsMap AM.empty qs
val countRef = ref (~1)
fun count () = (countRef := !countRef + 1; !countRef)
in
@@ -647,8 +649,31 @@ end = struct
val pureArgs = PS.difference (paths, invalPaths)
val shouldCache =
case getHeuristic () of
- Always => true
- | Never => (case qs of [_] => true | _ => false)
+ SmartEq =>
+ (case (qs, PS.numItems pureArgs) of
+ ((q::qs), 0) =>
+ let
+ val m = addToSqlArgsMap (q, AM.empty)
+ val ms = map (fn q => addToSqlArgsMap (q, AM.empty)) qs
+ fun test (m, acc) =
+ acc
+ <\obind\>
+ (fn m' =>
+ let
+ val mm = AM.unionWith #1 (m, m')
+ in
+ AM.numItems m = AM.numItems mm
+ <\oguard\>
+ (fn _ => SOME mm)
+ end)
+ in
+ case List.foldl test (SOME m) ms of
+ NONE => false
+ | SOME _ => true
+ end
+ | _ => false)
+ | Always => true
+ | Never => (case qs of [_] => PS.numItems pureArgs = 0 | _ => false)
| NoPureAll => (case qs of [] => false | _ => true)
| NoPureOne => (case qs of [] => false | _ => PS.numItems pureArgs = 0)
| NoCombo => PS.numItems pureArgs = 0 orelse AM.numItems argsMap = 0