explain logging and weight fixing
This commit is contained in:
parent
e1e95b9686
commit
e453385d5e
10 changed files with 95 additions and 14 deletions
|
|
@ -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,
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue