Пример #1
0
func (set *bindingSet) getNode(val *ast.ValueMap) *bindingSetNode {
	hashCode := val.Hash()
	for entry := set.table[hashCode]; entry != nil; entry = entry.next {
		if entry.val.Equal(val) {
			return entry
		}
	}
	return nil
}
Пример #2
0
func (set *bindingSet) Add(val *ast.ValueMap) {
	node := set.getNode(val)
	if node != nil {
		return
	}
	hashCode := val.Hash()
	head := set.table[hashCode]
	set.table[hashCode] = &bindingSetNode{val, head}
}
Пример #3
0
func newBindingsV1(locals *ast.ValueMap) (result []*bindingV1) {
	result = make([]*bindingV1, 0, locals.Len())
	locals.Iter(func(key, value ast.Value) bool {
		result = append(result, &bindingV1{
			Key:   &ast.Term{Value: key},
			Value: &ast.Term{Value: value},
		})
		return false
	})
	return result
}
Пример #4
0
func iterStorage(ctx context.Context, store Store, txn Transaction, nonGround, ground ast.Ref, bindings *ast.ValueMap, iter func(*ast.ValueMap, interface{})) error {

	if len(nonGround) == 0 {
		path, err := NewPathForRef(ground)
		if err != nil {
			return err
		}
		node, err := store.Read(ctx, txn, path)
		if err != nil {
			if IsNotFound(err) {
				return nil
			}
			return err
		}
		iter(bindings, node)
		return nil
	}

	head := nonGround[0]
	tail := nonGround[1:]

	headVar, isVar := head.Value.(ast.Var)

	if !isVar || len(ground) == 0 {
		ground = append(ground, head)
		return iterStorage(ctx, store, txn, tail, ground, bindings, iter)
	}

	path, err := NewPathForRef(ground)
	if err != nil {
		return err
	}

	node, err := store.Read(ctx, txn, path)
	if err != nil {
		if IsNotFound(err) {
			return nil
		}
		return err
	}

	switch node := node.(type) {
	case map[string]interface{}:
		for key := range node {
			ground = append(ground, ast.StringTerm(key))
			cpy := bindings.Copy()
			cpy.Put(headVar, ast.String(key))
			err := iterStorage(ctx, store, txn, tail, ground, cpy, iter)
			if err != nil {
				return err
			}
			ground = ground[:len(ground)-1]
		}
	case []interface{}:
		for i := range node {
			idx := ast.IntNumberTerm(i)
			ground = append(ground, idx)
			cpy := bindings.Copy()
			cpy.Put(headVar, idx.Value)
			err := iterStorage(ctx, store, txn, tail, ground, cpy, iter)
			if err != nil {
				return err
			}
			ground = ground[:len(ground)-1]
		}
	}

	return nil
}