循环依赖检查和排序

package main

import (

"fmt"

)

// Index 必须是从0开始依次递增的

var (

NormalNodes = []Node{

Node{

Index : 0,

Depends : []uint32{1,2,3},

},

Node{

Index : 1,

Depends : []uint32{2,3,7},

},

Node{

Index : 2,

Depends : []uint32{3},

},

Node{

Index : 3,

Depends : []uint32{4},

},

Node{

Index : 4,

Depends : []uint32{},

},

Node{

Index : 5,

Depends : []uint32{},

},

Node{

Index : 6,

Depends : []uint32{7},

},

Node{

Index : 7,

Depends : []uint32{5},

},

}

)

var (

ErrorNodes = []Node{

Node{

Index : 0,

Depends : []uint32{1,2,3},

},

Node{

Index : 1,

Depends : []uint32{2,3},

},

Node{

Index : 2,

Depends : []uint32{3},

},

Node{

Index : 3,

Depends : []uint32{4},

},

Node{

Index : 4,

Depends : []uint32{},

},

// 依赖不存在

Node{

Index : 5,

Depends : []uint32{99},

},

}

)

var (

RecursiveNodes = []Node{

Node{

Index : 0,

Depends : []uint32{1,2,3},

},

Node{

Index : 1,

Depends : []uint32{2,3},

},

Node{

Index : 2,

Depends : []uint32{3,5},

},

Node{

Index : 3,

Depends : []uint32{4},

},

Node{

Index : 4,

Depends : []uint32{},

},

// 循环依赖

Node{

Index : 5,

Depends : []uint32{0},

},

}

)

type Node struct {

Index uint32

Depends []uint32

}

func CheckDependExisted(nodes []Node) (error) {

fmt.Printf("CheckDependExisted ...\n")

for _,n := range nodes {

for _,index := range n.Depends {

existed := false

for _,n := range nodes {

if index == n.Index {

existed = true

}

}

if !existed {

return fmt.Errorf("not found dpends for node[%v]", n)

}

}

}

return nil

}

func CheckDependRecursive(nodes []Node) (error) {

fmt.Printf("CheckDependRecursive ...\n")

for _,n := range nodes {

dependsIndex := []uint32{}

err := DeepFirstCheck(n, &dependsIndex, &nodes)

if err != nil {

return err

}

}

return nil

}

func DeepFirstCheck(curnode Node, pathIndexs *[]uint32, globalNodes *[]Node) (error) {

fmt.Printf("DeepFirstCheck,currentIndex[%d],curpath[%v]\n", curnode.Index, *pathIndexs)

// 检查当前节点是否已经在路径里,如果是,则表示有循环依赖

for _,v := range *pathIndexs {

if v == curnode.Index {

newpathIndex := append(*pathIndexs, curnode.Index)

return fmt.Errorf("found recursive dpends [%v]", newpathIndex)

}

}

// 将当前索引保存到路径里

newpathIndex := append(*pathIndexs, curnode.Index)

pathIndexs = &newpathIndex

for _,index := range curnode.Depends {

err := DeepFirstCheck((*globalNodes)[index], pathIndexs, globalNodes)

if err != nil {

return err

}

}

return nil

}

func getPos(n Node, seq []uint32) (uint32,error) {

for i,vIndex := range seq {

if vIndex == n.Index {

return uint32(i), nil

}

}

return 0, fmt.Errorf("failed to get pos for node[%v]", n)

}

// bool : 是否有触发交换

func swapdepends(nodes []Node, indexSeqBefore []uint32) (bool,[]uint32, error) {

fmt.Printf("swapdepends ...\n")

indexSeq := indexSeqBefore

changed := false

for _,vNode := range nodes {

// 如果节点没有依赖,则不处理

if vNode.Depends == nil || len(vNode.Depends) == 0 {

continue

}

// 先找到本节点的在排序中的位置

curPos,err := getPos(vNode, indexSeq)

if err != nil {

return false,nil,err

}

// 找到依赖节点的最大索引值

maxDependsPos := uint32(0)

for _, vIndex := range vNode.Depends {

curPos,err := getPos(nodes[vIndex], indexSeq)

if err != nil {

return false,nil,err

}

if maxDependsPos < curPos {

maxDependsPos = curPos

}

}

// 如果当前节点索引位置 < 最大的依赖索引位置,则进行交换

if curPos < maxDependsPos {

fmt.Printf("ready swap for node [%d %d],", indexSeq[curPos],indexSeq[maxDependsPos])

temp := indexSeq[curPos]

indexSeq[curPos] = indexSeq[maxDependsPos]

indexSeq[maxDependsPos] = temp

fmt.Printf("after swap seq [%v]\n", indexSeq)

changed = true

}

}

return changed,indexSeq,nil

}

func SortNode (nodes []Node) ([]uint32, error) {

fmt.Printf("SortNode ...\n")

indexSeq := []uint32{}

for _,v := range nodes {

indexSeq = append(indexSeq, v.Index)

}

fmt.Printf("init seq [%v]\n", indexSeq)

changed,newseq,err := swapdepends(nodes, indexSeq)

for maxSwapCounter := 100;maxSwapCounter>0;maxSwapCounter-- {

if err != nil {

return nil, err

}

if !changed {

return newseq,nil

}

changed,newseq,err = swapdepends(nodes, newseq)

}

return nil, fmt.Errorf("failed to sort for[%v]", nodes)

}

func CheckAndSort (nodes []Node) ([]uint32, error) {

err := CheckDependExisted(nodes)

if err != nil {

fmt.Printf("failed to check depends for [%v]\n", err)

return nil, err

}

err = CheckDependRecursive(nodes)

if err != nil {

fmt.Printf("failed to check depends for [%v]\n", err)

return nil, err

}

sortedseq,err := SortNode(nodes)

if err != nil {

fmt.Printf("failed to sort for [%v]\n", err)

return nil, err

}

fmt.Printf("sorted seq [%v]\n", sortedseq)

return sortedseq, nil

}

func main () {

fmt.Printf("main ...\n")

fmt.Printf("\n------------------check for normal nodes----------------------\n\n")

CheckAndSort(NormalNodes)

fmt.Printf("\n------------------check for not existed nodes----------------------\n\n")

CheckAndSort(ErrorNodes)

fmt.Printf("\n------------------check for recursive nodes----------------------\n\n")

CheckAndSort(RecursiveNodes)

}

你可能感兴趣的:(循环依赖检查和排序)