luis пре 7 година
родитељ
комит
2389794a9b
2 измењених фајлова са 80 додато и 22 уклоњено
  1. 17 4
      go/src/flow/flow.go
  2. 63 18
      go/src/flow/flow_test.go

+ 17 - 4
go/src/flow/flow.go

@@ -3,6 +3,7 @@ package flow
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
 	"flow/registry"
 	"fmt"
 	"io"
@@ -28,6 +29,7 @@ type Flow struct {
 	sync.Mutex
 
 	registry   *registry.R
+	idGen      func() string
 	consts     map[string]Data
 	data       map[string]Data // Should be named, to fetch later
 	operations sync.Map
@@ -44,6 +46,7 @@ type Flow struct {
 func New() *Flow {
 	return &Flow{
 		registry: registry.Global,
+		idGen:    func() string { return RandString(8) },
 		// Data
 		consts:     map[string]Data{},
 		data:       map[string]Data{},
@@ -74,6 +77,12 @@ func (f *Flow) SetRegistry(r *registry.R) *Flow {
 	return f
 }
 
+//SetIDGen set the id generator that will generate
+//ID for new nodes
+func (f *Flow) SetIDGen(idGen func() string) {
+	f.idGen = idGen
+}
+
 // DefOp Manual tag an Operation
 func (f *Flow) DefOp(id string, name string, params ...interface{}) Operation {
 	inputs := make([]*operation, len(params))
@@ -127,28 +136,32 @@ func (f *Flow) Op(name string, params ...interface{}) Operation {
 		return opNil(f)
 	}
 	// generate ID
-	for {
-		id := RandString(8)
+	for i := 0; i < 10; i++ {
+		id := f.idGen()
 		if _, ok := f.operations.Load(id); ok {
 			continue
 		}
 		f.operations.Store(id, &opEntry{sync.Mutex{}, name, inputs, executor})
 		return opFunc(f, id)
 	}
+	f.err = errors.New("ID exausted")
+	return opNil(f)
 	// Initialize opfunc maybe
 }
 
 // Const returns a const operation
 func (f *Flow) Const(value Data) Operation {
 	// generate ID
-	for {
-		id := RandString(8)
+	for i := 0; i < 10; i++ {
+		id := f.idGen()
 		if _, ok := f.consts[id]; ok {
 			continue
 		}
 		f.consts[id] = value
 		return opConst(f, id)
 	}
+	f.err = errors.New("ID exausted")
+	return opNil(f)
 }
 
 // Var operation

+ 63 - 18
go/src/flow/flow_test.go

@@ -3,6 +3,8 @@ package flow_test
 import (
 	"bytes"
 	"encoding/json"
+	"errors"
+	"log"
 	"testing"
 	"time"
 
@@ -17,6 +19,67 @@ import (
 func init() {
 	assert.Quiet = true
 }
+func TestError(t *testing.T) {
+	a := assert.A(t)
+
+	f := flow.New()
+	err := errors.New("test")
+	f.Err(err)
+	a.Eq(f.Err(), err, "error should be the same")
+}
+func TestDefOp(t *testing.T) {
+	a := assert.A(t)
+	f := flow.New()
+
+	f.DefOp("2", "vecadd", []float32{1, 1, 1}, []float32{2, 2, 2}) // r:3 3 3
+	a.Eq(f.Err(), nil, "doing DefOp")
+
+	f.DefOp("1", "vecadd", []float32{1, 2, 3}, f.Res("2")) // r: 4 5 6
+	a.Eq(f.Err(), nil, "doing DefOp")
+
+	op := f.Op("vecmul", f.Res("1"), []float32{2, 2, 2}) //r:8 10 12
+	a.Eq(f.Err(), nil, "mul operation")
+	a.NotEq(op, nil, "operation not nil")
+
+	desired := []float32{8, 10, 12}
+	res := op.Process()
+	a.Eq(desired, res, "vector result should match")
+
+	op = f.DefOp("123", "none")
+	op.Process()
+	a.NotEq(f.Err(), nil, "Error should not be nil")
+}
+
+func TestIDGen(t *testing.T) {
+	a := assert.A(t)
+	idTable := []string{"2", "1", "1"}
+
+	f := flow.New()
+	f.SetIDGen(func() string {
+		log.Println("Requesting ID", len(idTable))
+		if len(idTable) == 0 {
+			return "0"
+		}
+		newID := idTable[len(idTable)-1]
+		t.Log("Returning ID", newID)
+		idTable = idTable[:len(idTable)-1]
+		return newID
+	})
+
+	o := f.Op("vecadd", f.In(0), f.In(1))
+	a.Eq(f.Err(), nil, "Should not nil")
+	a.Eq(o.ID(), "1", "id should be 1")
+
+	o = f.Op("vecadd", f.In(0), f.In(1))
+	a.Eq(f.Err(), nil, "Should not nil")
+	a.Eq(o.ID(), "2", "id should be 2")
+
+	c := f.Const(1)
+	f.Const(1)
+	o = f.Op("vecadd", f.In(0), c)
+	a.NotEq(f.Err(), nil, "Should be nil,id generation exausted")
+
+}
 
 func TestSerialize(t *testing.T) {
 	// Does not text yet
@@ -112,24 +175,6 @@ func TestCache(t *testing.T) {
 		assert.Eq(t, res, 4)
 	}
 }
-func TestDefOp(t *testing.T) {
-	a := assert.A(t)
-	f := flow.New()
-
-	f.DefOp("2", "vecadd", []float32{1, 1, 1}, []float32{2, 2, 2}) // r:3 3 3
-	a.Eq(f.Err(), nil, "doing DefOp")
-
-	f.DefOp("1", "vecadd", []float32{1, 2, 3}, f.Res("2")) // r: 4 5 6
-	a.Eq(f.Err(), nil, "doing DefOp")
-
-	op := f.Op("vecmul", f.Res("1"), []float32{2, 2, 2}) //r:8 10 12
-	a.Eq(f.Err(), nil, "mul operation")
-	a.NotEq(op, nil, "operation not nil")
-
-	desired := []float32{8, 10, 12}
-	res := op.Process()
-	a.Eq(desired, res, "vector result should match")
-}
 
 func TestHandler(t *testing.T) {
 	f, op := prepareComplex()