From d4d712a3a0953fb7886c3a6fe540a12242d79985 Mon Sep 17 00:00:00 2001 From: codebear801 Date: Mon, 20 Apr 2020 14:33:58 -0700 Subject: [PATCH] feat: implment node container issue: https://github.com/Telenav/osrm-backend/issues/289 --- .../oasis/stationgraph/node_container.go | 76 +++++ .../oasis/stationgraph/node_container_test.go | 288 ++++++++++++++++++ 2 files changed, 364 insertions(+) create mode 100644 integration/service/oasis/stationgraph/node_container.go create mode 100644 integration/service/oasis/stationgraph/node_container_test.go diff --git a/integration/service/oasis/stationgraph/node_container.go b/integration/service/oasis/stationgraph/node_container.go new file mode 100644 index 00000000000..514d23b8adc --- /dev/null +++ b/integration/service/oasis/stationgraph/node_container.go @@ -0,0 +1,76 @@ +package stationgraph + +import "github.com/Telenav/osrm-backend/integration/service/oasis/chargingstrategy" + +type logicNodeIdentifier2NodePtr map[logicNodeIdentifier]*node +type nodeID2NodePtr map[nodeID]*node +type nodeID2StationID map[nodeID]string + +type nodeContainer struct { + logicNode2NodePtr logicNodeIdentifier2NodePtr + id2NodePtr nodeID2NodePtr + id2StationID nodeID2StationID + counter int +} + +func newNodeContainer() *nodeContainer { + return &nodeContainer{ + logicNode2NodePtr: make(logicNodeIdentifier2NodePtr), + id2NodePtr: make(nodeID2NodePtr), + id2StationID: make(nodeID2StationID), + counter: 0, + } +} + +func (nc *nodeContainer) addNode(stationID string, targetState chargingstrategy.State, location locationInfo) *node { + key := logicNodeIdentifier{stationID, targetState} + + if n, ok := nc.logicNode2NodePtr[key]; ok { + return n + } else { + n = &node{ + id: (nodeID(nc.counter)), + chargeInfo: chargeInfo{ + arrivalEnergy: 0.0, + chargeTime: 0.0, + targetState: targetState, + }, + locationInfo: location, + } + nc.logicNode2NodePtr[key] = n + nc.id2NodePtr[n.id] = n + nc.id2StationID[n.id] = stationID + nc.counter++ + + return n + } +} + +func (nc *nodeContainer) getNode(id nodeID) *node { + if n, ok := nc.id2NodePtr[id]; ok { + return n + } else { + return nil + } + +} + +func (nc *nodeContainer) isNodeVisited(id nodeID) bool { + _, ok := nc.id2NodePtr[id] + return ok +} + +func (nc *nodeContainer) stationID(id nodeID) string { + if stationID, ok := nc.id2StationID[id]; ok { + return stationID + } else { + return invalidStationID + } +} + +const invalidStationID = "InvalidStationID" + +type logicNodeIdentifier struct { + stationID string + targetState chargingstrategy.State +} diff --git a/integration/service/oasis/stationgraph/node_container_test.go b/integration/service/oasis/stationgraph/node_container_test.go new file mode 100644 index 00000000000..ed5e1076249 --- /dev/null +++ b/integration/service/oasis/stationgraph/node_container_test.go @@ -0,0 +1,288 @@ +package stationgraph + +import ( + "math/rand" + "reflect" + "testing" + "time" + + "github.com/Telenav/osrm-backend/integration/service/oasis/chargingstrategy" +) + +func TestAddAndGetFunctionsForNodeContainer(t *testing.T) { + input := []struct { + stationID string + chargeState chargingstrategy.State + location locationInfo + }{ + { + "station1", + chargingstrategy.State{ + Energy: 10.0, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + { + "station1", + chargingstrategy.State{ + Energy: 20.0, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + { + "station1", + chargingstrategy.State{ + Energy: 30.0, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + { + "station2", + chargingstrategy.State{ + Energy: 10.0, + }, + locationInfo{ + lat: 2.2, + lon: 2.2, + }, + }, + { + "station2", + chargingstrategy.State{ + Energy: 20.0, + }, + locationInfo{ + lat: 2.2, + lon: 2.2, + }, + }, + { + "station3", + chargingstrategy.State{ + Energy: 15.0, + }, + locationInfo{ + lat: 3.3, + lon: 3.3, + }, + }, + } + + expect := []struct { + n *node + stationID string + }{ + { + &node{ + 0, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 10.0, + }, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + "station1", + }, + { + &node{ + 1, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 20.0, + }, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + "station1", + }, + { + &node{ + 2, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 30.0, + }, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + "station1", + }, + { + &node{ + 3, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 10.0, + }, + }, + locationInfo{ + lat: 2.2, + lon: 2.2, + }, + }, + "station2", + }, + { + &node{ + 4, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 20.0, + }, + }, + locationInfo{ + lat: 2.2, + lon: 2.2, + }, + }, + "station2", + }, + { + &node{ + 5, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 15.0, + }, + }, + locationInfo{ + lat: 3.3, + lon: 3.3, + }, + }, + "station3", + }, + } + + if len(input) != len(expect) { + t.Errorf("Incorrect test case, array of input and array of expect should 1-to-1 match.\n") + } + + nc := newNodeContainer() + + for i := 0; i < len(input); i++ { + tmpNode := nc.addNode(input[i].stationID, input[i].chargeState, input[i].location) + + if !reflect.DeepEqual(tmpNode, expect[i].n) { + t.Errorf("Calling nodeContainer's addNode() generate incorrect result, expect %#v but got %#v.\n", expect[i].n, tmpNode) + } + } + + for i := 0; i < len(input); i++ { + isVisited := nc.isNodeVisited((nodeID)(i)) + if !isVisited { + t.Errorf("Calling nodeContainer's isNodeVisited() generate incorrect result, expect node %v is visited but returns no.\n", i) + } + + tmpNode := nc.getNode((nodeID)(i)) + if !reflect.DeepEqual(tmpNode, expect[i].n) { + t.Errorf("Calling nodeContainer's getNode() generate incorrect result, expect %#v but got %#v.\n", expect[i].n, tmpNode) + } + + tmpStationID := nc.stationID((nodeID)(i)) + if !reflect.DeepEqual(tmpStationID, expect[i].stationID) { + t.Errorf("Calling nodeContainer's stationID() generate incorrect result, expect %#v but got %#v.\n", expect[i].stationID, tmpStationID) + } + } + + rand.Seed(time.Now().UnixNano()) + for i := 0; i < 10; i++ { + randomGen := func(min, max int) int { + return rand.Intn(max-min) + min + } + unVisitedNodeID := randomGen(7, 100) + isVisited := nc.isNodeVisited((nodeID)(unVisitedNodeID)) + if isVisited { + t.Errorf("Calling nodeContainer's isNodeVisited() generate incorrect result, expect node %v is unvisited but returns yes.\n", unVisitedNodeID) + } + } + +} + +func TestAddDuplicateNodeForNodeContainer(t *testing.T) { + input := []struct { + stationID string + chargeState chargingstrategy.State + location locationInfo + }{ + { + "station1", + chargingstrategy.State{ + Energy: 10.0, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + { + "station1", + chargingstrategy.State{ + Energy: 10.0, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + { + "station1", + chargingstrategy.State{ + Energy: 10.0, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + } + + expect := struct { + n *node + stationID string + }{ + &node{ + 0, + chargeInfo{ + targetState: chargingstrategy.State{ + Energy: 10.0, + }, + }, + locationInfo{ + lat: 1.1, + lon: 1.1, + }, + }, + "station1", + } + + nc := newNodeContainer() + + for i := 0; i < len(input); i++ { + tmpNode := nc.addNode(input[i].stationID, input[i].chargeState, input[i].location) + + if !reflect.DeepEqual(tmpNode, expect.n) { + t.Errorf("Calling nodeContainer's addNode() generate incorrect result, expect %#v but got %#v.\n", expect.n, tmpNode) + } + } + +}