explain logging and weight fixing

This commit is contained in:
Barak Michener 2014-08-16 05:19:16 -04:00
parent e1e95b9686
commit e453385d5e
10 changed files with 95 additions and 14 deletions

View file

@ -17,6 +17,8 @@ package iterator
import (
"sort"
"github.com/barakmich/glog"
"github.com/google/cayley/graph"
)
@ -68,7 +70,7 @@ func (it *And) Optimize() (graph.Iterator, bool) {
// And now, without changing any of the iterators, we reorder them. it_list is
// now a permutation of itself, but the contents are unchanged.
its = optimizeOrder(its)
its = it.optimizeOrder(its)
its = materializeIts(its)
@ -87,6 +89,7 @@ func (it *And) Optimize() (graph.Iterator, bool) {
newAnd.tags.CopyFrom(it)
newAnd.optimizeContains()
glog.V(3).Infoln(it.UID(), "became", newAnd.UID())
// And close ourselves but not our subiterators -- some may still be alive in
// the new And (they were unchanged upon calling Optimize() on them, at the
@ -133,7 +136,7 @@ func (_ *And) optimizeReplacement(its []graph.Iterator) graph.Iterator {
// optimizeOrder(l) takes a list and returns a list, containing the same contents
// but with a new ordering, however it wishes.
func optimizeOrder(its []graph.Iterator) []graph.Iterator {
func (it *And) optimizeOrder(its []graph.Iterator) []graph.Iterator {
var (
// bad contains iterators that can't be (efficiently) nexted, such as
// graph.Optional or graph.Not. Separate them out and tack them on at the end.
@ -146,29 +149,35 @@ func optimizeOrder(its []graph.Iterator) []graph.Iterator {
// Total cost is defined as The Next()ed iterator's cost to Next() out
// all of it's contents, and to Contains() each of those against everyone
// else.
for _, it := range its {
if _, canNext := it.(graph.Nexter); !canNext {
bad = append(bad, it)
for _, root := range its {
if _, canNext := root.(graph.Nexter); !canNext {
bad = append(bad, root)
continue
}
rootStats := it.Stats()
rootStats := root.Stats()
cost := rootStats.NextCost
for _, f := range its {
if _, canNext := it.(graph.Nexter); !canNext {
if _, canNext := f.(graph.Nexter); !canNext {
continue
}
if f == it {
if f == root {
continue
}
stats := f.Stats()
cost += stats.ContainsCost
cost += stats.ContainsCost * (rootStats.Size / (stats.Size + 1))
}
cost *= rootStats.Size
if glog.V(3) {
glog.V(3).Infoln("And:", it.UID(), "Root:", root.UID(), "Total Cost:", cost, "Best:", bestCost)
}
if cost < bestCost {
best = it
best = root
bestCost = cost
}
}
if glog.V(3) {
glog.V(3).Infoln("And:", it.UID(), "Choosing:", best.UID(), "Best:", bestCost)
}
// TODO(barakmich): Optimization of order need not stop here. Picking a smart
// Contains() order based on probability of getting a false Contains() first is
@ -320,7 +329,7 @@ func (it *And) Stats() graph.IteratorStats {
Size := primaryStats.Size
for _, sub := range it.internalIterators {
stats := sub.Stats()
NextCost += stats.ContainsCost
NextCost += stats.ContainsCost * (primaryStats.Size / (stats.Size + 1))
ContainsCost += stats.ContainsCost
if Size > stats.Size {
Size = stats.Size
@ -330,6 +339,8 @@ func (it *And) Stats() graph.IteratorStats {
ContainsCost: ContainsCost * 2,
NextCost: NextCost,
Size: Size,
Next: it.runstats.Next,
Contains: it.runstats.Contains,
}
}