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 }
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} }
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 }
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 }