func extensionsFromEmbeddings(dt *Digraph, pattern *subgraph.SubGraph, ei subgraph.EmbIterator, seen map[int]bool) (total int, overlap []map[int]bool, fisEmbs []*subgraph.Embedding, sets []*hashtable.LinearHash, exts types.Set) { if dt.Mode&FIS == FIS { seen = make(map[int]bool) fisEmbs = make([]*subgraph.Embedding, 0, 10) } else { sets = make([]*hashtable.LinearHash, len(pattern.V)) } if dt.Mode&OverlapPruning == OverlapPruning { overlap = make([]map[int]bool, len(pattern.V)) } exts = set.NewSetMap(hashtable.NewLinearHash()) add := validExtChecker(dt, func(emb *subgraph.Embedding, ext *subgraph.Extension) { exts.Add(ext) }) for emb, next := ei(false); next != nil; emb, next = next(false) { seenIt := false for idx, id := range emb.Ids { if fisEmbs != nil { if seen[id] { seenIt = true } } if overlap != nil { if overlap[idx] == nil { overlap[idx] = make(map[int]bool) } overlap[idx][id] = true } if seen != nil { seen[id] = true } if sets != nil { if sets[idx] == nil { sets[idx] = hashtable.NewLinearHash() } set := sets[idx] if !set.Has(types.Int(id)) { set.Put(types.Int(id), emb) } } for _, e := range dt.G.Kids[id] { add(emb, &dt.G.E[e], idx, -1) } for _, e := range dt.G.Parents[id] { add(emb, &dt.G.E[e], -1, idx) } } if fisEmbs != nil && !seenIt { fisEmbs = append(fisEmbs, emb) } total++ } return total, overlap, fisEmbs, sets, exts }
func findChildren(n Node, allow func(*subgraph.SubGraph) (bool, error), debug bool) (nodes []lattice.Node, err error) { if debug { errors.Logf("CHILDREN-DEBUG", "node %v", n) } dt := n.dt() sg := n.SubGraph() patterns, err := extendNode(dt, n, debug) if err != nil { return nil, err } unsupEmbs, err := n.UnsupportedEmbs() if err != nil { return nil, err } unsupExts, err := n.UnsupportedExts() if err != nil { return nil, err } newUnsupportedExts := unsupExts.Copy() nOverlap, err := n.Overlap() if err != nil { return nil, err } var wg sync.WaitGroup type nodeEp struct { n lattice.Node vord []int } nodeCh := make(chan nodeEp) vords := make([][]int, 0, 10) go func() { for nep := range nodeCh { nodes = append(nodes, nep.n) vords = append(vords, nep.vord) wg.Done() } }() epCh := make(chan *subgraph.Extension) go func() { for ep := range epCh { newUnsupportedExts.Add(ep) wg.Done() } }() errorCh := make(chan error) errs := make([]error, 0, 10) go func() { for err := range errorCh { errs = append(errs, err) wg.Done() } }() for k, v, next := patterns.Iterate()(); next != nil; k, v, next = next() { err := dt.pool.Do(func(pattern *subgraph.SubGraph, i *extInfo) func() { wg.Add(1) return func() { if allow != nil { if allowed, err := allow(pattern); err != nil { errorCh <- err return } else if !allowed { wg.Done() return } } ep := i.ep vord := i.vord tu := set.NewSetMap(hashtable.NewLinearHash()) for i, next := unsupExts.Items()(); next != nil; i, next = next() { tu.Add(i.(*subgraph.Extension).Translate(len(sg.V), vord)) } pOverlap := translateOverlap(nOverlap, vord) tUnsupEmbs := unsupEmbs.Translate(len(sg.V), vord).Set() support, exts, embs, overlap, dropped, err := ExtsAndEmbs(dt, pattern, pOverlap, tu, tUnsupEmbs, dt.Mode, debug) if err != nil { errorCh <- err return } if debug { errors.Logf("CHILDREN-DEBUG", "pattern %v support %v exts %v", pattern.Pretty(dt.Labels), len(embs), len(exts)) } if support >= dt.Support() { nodeCh <- nodeEp{n.New(pattern, exts, embs, overlap, dropped), vord} } else { epCh <- ep } } }(k.(*subgraph.SubGraph), v.(*extInfo))) if err != nil { return nil, err } } wg.Wait() close(nodeCh) close(epCh) close(errorCh) if len(errs) > 0 { e := errors.Errorf("findChildren error").(*errors.Error) for _, err := range errs { e.Chain(err) } return nil, e } for i, newNode := range nodes { err := newNode.(Node).SaveUnsupportedExts(len(sg.V), vords[i], newUnsupportedExts) if err != nil { return nil, err } } return nodes, nil }
func extensionsFromFreqEdges(dt *Digraph, pattern *subgraph.SubGraph, ei subgraph.EmbIterator, seen map[int]bool) (total int, overlap []map[int]bool, fisEmbs []*subgraph.Embedding, sets []*hashtable.LinearHash, exts types.Set) { if dt.Mode&FIS == FIS { seen = make(map[int]bool) fisEmbs = make([]*subgraph.Embedding, 0, 10) } else { sets = make([]*hashtable.LinearHash, len(pattern.V)) } if dt.Mode&OverlapPruning == OverlapPruning { overlap = make([]map[int]bool, len(pattern.V)) } support := dt.Support() done := make(chan types.Set) go func(done chan types.Set) { exts := make(chan *subgraph.Extension, len(pattern.V)) go func() { hash := set.NewSetMap(hashtable.NewLinearHash()) for ext := range exts { if !pattern.HasExtension(ext) { hash.Add(ext) } } done <- hash close(done) }() for i := range pattern.V { u := &pattern.V[i] for _, e := range dt.Indices.EdgesFromColor[u.Color] { for j := range pattern.V { v := &pattern.V[j] if v.Color == e.TargColor { ep := subgraph.NewExt( subgraph.Vertex{Idx: i, Color: e.SrcColor}, subgraph.Vertex{Idx: j, Color: e.TargColor}, e.EdgeColor) exts <- ep } } ep := subgraph.NewExt( subgraph.Vertex{Idx: i, Color: u.Color}, subgraph.Vertex{Idx: len(pattern.V), Color: e.TargColor}, e.EdgeColor) exts <- ep } for _, e := range dt.Indices.EdgesToColor[u.Color] { ep := subgraph.NewExt( subgraph.Vertex{Idx: len(pattern.V), Color: e.SrcColor}, subgraph.Vertex{Idx: i, Color: u.Color}, e.EdgeColor) exts <- ep } } close(exts) }(done) stop := false for emb, next := ei(stop); next != nil; emb, next = next(stop) { min := -1 seenIt := false for idx, id := range emb.Ids { if fisEmbs != nil { if seen[id] { seenIt = true } } if overlap != nil { if overlap[idx] == nil { overlap[idx] = make(map[int]bool) } overlap[idx][id] = true } if seen != nil { seen[id] = true } if sets != nil { if sets[idx] == nil { sets[idx] = hashtable.NewLinearHash() } set := sets[idx] if !set.Has(types.Int(id)) { set.Put(types.Int(id), emb) } size := set.Size() if min == -1 || size < min { min = size } } } if fisEmbs != nil && !seenIt { fisEmbs = append(fisEmbs, emb) min = len(fisEmbs) } total++ if min >= support { stop = true } } if total < support { return total, overlap, fisEmbs, sets, nil } return total, overlap, fisEmbs, sets, <-done }