Esempio n. 1
0
func cachedAdj(n Node, dt *Digraph, count bytes_int.MultiMap, cache bytes_bytes.MultiMap) (nodes []lattice.Node, has bool, err error) {
	if dt.Mode&Caching == 0 {
		return nil, false, nil
	}
	dt.lock.RLock()
	defer dt.lock.RUnlock()
	key := n.Label()
	if has, err := count.Has(key); err != nil {
		return nil, false, err
	} else if !has {
		return nil, false, nil
	}
	// errors.Logf("DEBUG", "loading %v", n)
	err = cache.DoFind(key, func(_, adj []byte) (err error) {
		// WHY DO WE NEED TO UNLOCK?
		// We will aquire this lock in the course of LoadEmbList in READ MODE
		// This is fine to re-aquire in READ
		// However, if another thread tries to aquire in WRITE before we re-aquire
		// There will be a waiting WRITE when we try to aquire READ
		// A waiting WRITE will prevent all READ aquisitions
		// DEADLOCK.
		dt.lock.RUnlock()
		defer dt.lock.RLock()
		node, err := LoadEmbListNode(dt, adj)
		if err != nil {
			return err
		}
		if node == nil {
			errors.Logf("ERROR", "node is nil")
			panic("node was nil")
		}
		nodes = append(nodes, node)
		return nil
	})
	if err != nil {
		return nil, false, err
	}
	if false {
		pat, _ := LoadSubgraphPattern(dt, key)
		errors.Logf("LOAD-DEBUG", "Loaded Cached Adj %v adj %v", pat.Pat, len(nodes))
	}
	return nodes, true, nil
}
Esempio n. 2
0
File: count.go Progetto: timtadh/sfp
func count(n Node, compute func() ([]lattice.Node, error), counts bytes_int.MultiMap) (int, error) {
	if has, err := counts.Has(n.Label()); err != nil {
		return 0, err
	} else if !has {
		nodes, err := compute()
		if err != nil {
			return 0, err
		}
		return len(nodes), nil
	}
	var count int32
	err := counts.DoFind(n.Label(), func(_ []byte, c int32) error {
		count = c
		return nil
	})
	if err != nil {
		return 0, err
	}
	return int(count), nil
}
Esempio n. 3
0
func cacheAdj(dt *Digraph, count bytes_int.MultiMap, cache bytes_bytes.MultiMap, key []byte, nodes []lattice.Node) (err error) {
	if dt.Mode&Caching == 0 {
		return nil
	}
	dt.lock.Lock()
	defer dt.lock.Unlock()
	if has, err := count.Has(key); err != nil {
		return err
	} else if has {
		return nil
	}
	err = count.Add(key, int32(len(nodes)))
	if err != nil {
		return err
	}
	for _, n := range nodes {
		err = cache.Add(key, n.Pattern().Label())
		if err != nil {
			return err
		}
	}
	return nil
}