Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}