Example #1
0
File: node.go Project: timtadh/sfp
func (n *Node) Parents() ([]lattice.Node, error) {
	if n.pat.Items.Size() == 0 {
		return []lattice.Node{}, nil
	} else if n.pat.Items.Size() == 1 {
		return []lattice.Node{n.dt.empty}, nil
	}
	i := setToInt32s(n.pat.Items)
	if has, err := n.dt.ParentCount.Has(i); err != nil {
		return nil, err
	} else if has {
		return n.cached(n.dt.Parents, i)
	}
	parents := make([]*set.SortedSet, 0, n.pat.Items.Size())
	for item, next := n.pat.Items.Items()(); next != nil; item, next = next() {
		parent := n.pat.Items.Copy()
		parent.Delete(item)
		parents = append(parents, parent)
	}
	nodes := make([]lattice.Node, 0, 10)
	for _, items := range parents {
		if node, err := TryLoadNode(setToInt32s(items), n.dt); err != nil {
			return nil, err
		} else if node != nil {
			nodes = append(nodes, node)
			continue
		}
		ctxs := int32sToSet(n.txs)
		var txs types.Set
		for item, next := items.Items()(); next != nil; item, next = next() {
			mytxs := set.NewSortedSet(len(n.txs) + 10)
			for _, tx := range n.dt.InvertedIndex[item.(types.Int32)] {
				if !ctxs.Has(types.Int32(tx)) {
					mytxs.Add(types.Int32(tx))
				}
			}
			var err error
			if txs == nil {
				txs = mytxs
			} else {
				txs, err = txs.Intersect(mytxs)
				if err != nil {
					return nil, err
				}
			}
		}
		txs, err := txs.Union(ctxs)
		if err != nil {
			return nil, err
		}
		stxs := make([]int32, 0, txs.Size())
		for item, next := txs.Items()(); next != nil; item, next = next() {
			stxs = append(stxs, int32(item.(types.Int32)))
		}
		node := &Node{Pattern{items}, n.dt, stxs}
		err = node.Save()
		if err != nil {
			return nil, err
		}
		nodes = append(nodes, node)
	}
	err := n.cache(n.dt.ParentCount, n.dt.Parents, i, nodes)
	if err != nil {
		return nil, err
	}
	return nodes, nil
}