mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-15 19:24:47 +08:00
233 lines
5.9 KiB
Go
233 lines
5.9 KiB
Go
// Package route
|
||
// @Author: Wang Feng
|
||
// @Description:
|
||
// @Version: 0.1.0
|
||
// @Date: 2022/5/9 17:30
|
||
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
||
//
|
||
|
||
package route
|
||
|
||
import (
|
||
"errors"
|
||
"mlsr/lsa"
|
||
"mlsr/lsdb"
|
||
"sync"
|
||
)
|
||
|
||
type RoutingTableCalculator struct {
|
||
// 邻接矩阵
|
||
adjMatrix [][]uint64
|
||
// 路由器数目
|
||
m_nRouters int
|
||
|
||
vNoLink int
|
||
links []int
|
||
linkCosts []uint64
|
||
}
|
||
|
||
//
|
||
// SetRouterNum
|
||
// @Description: 设置路由器个数
|
||
// @receiver c
|
||
// @param n
|
||
//
|
||
func (c *RoutingTableCalculator) SetRouterNum(n int) {
|
||
c.m_nRouters = n
|
||
}
|
||
|
||
//
|
||
// allocateAdjMatrix
|
||
// @Description: 给邻接矩阵分配所需的空间
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) allocateAdjMatrix() {
|
||
c.adjMatrix = make([][]uint64, c.m_nRouters)
|
||
// 根据路由器的数目,确定邻接矩阵的长度
|
||
for i := 0; i < c.m_nRouters; i++ {
|
||
c.adjMatrix[i] = make([]uint64, c.m_nRouters)
|
||
}
|
||
}
|
||
|
||
//
|
||
// initMatrix
|
||
// @Description: 为矩阵的每个单元设置非邻接成本(NON_ADJACENT_COST,如-12345),以确保内存安全。
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) initMatrix() {
|
||
for i := 0; i < c.m_nRouters; i++ {
|
||
for j := 0; j < c.m_nRouters; j++ {
|
||
c.adjMatrix[0][0] = NON_ADJACENT_COST
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// makeAdjMatrix
|
||
// @Description: 构建一个要去计算的邻接矩阵
|
||
// @receiver c
|
||
// @param lsdb
|
||
// @param p
|
||
//
|
||
func (c *RoutingTableCalculator) makeAdjMatrix(lsdb *lsdb.Lsdb,
|
||
rp *RouterMap) error {
|
||
// 1. 在Map中表示每个LSA
|
||
// 先从Lsdb中取出邻接LSA
|
||
lsas, err := lsdb.GetLSAsByType(lsa.LsaADJACENCYType)
|
||
if err != nil {
|
||
return errors.New("No Found adj lsa in LSDB. ")
|
||
}
|
||
// 2. 再对每个lsa进行操作
|
||
for i := 0; i < len(lsas); i++ {
|
||
// 2.1 取出源路由器,找其索引值,作为邻接矩阵的行号
|
||
row, b := rp.GetMappingNoByRouterName(lsas[i].GetOriginRouter())
|
||
if !b {
|
||
return errors.New("No Found origin router in routerMap. ")
|
||
}
|
||
// 2.2 依次取出该源路由器对应的所有邻接路由器标识,以及链路开销,来构建邻接矩阵
|
||
adjlsa, ok := (lsas[i]).(*lsa.AdjLsa)
|
||
if !ok {
|
||
return errors.New("Lsa from LSDB is not adjlsa. ")
|
||
}
|
||
adjs := adjlsa.GetAdjList()
|
||
for j := 0; j < len(adjs); j++ {
|
||
// 2.2.1 取列数
|
||
col, b := rp.GetMappingNoByRouterName(adjs[j].GetNeighborRouterIdentifier())
|
||
if !b {
|
||
return errors.New("No Found neighbor router in routerMap. ")
|
||
}
|
||
// 2.2.2 取开销
|
||
linkCost := adjs[j].AdjLsaLinkCost.LinkCost()
|
||
// 2.2.3 将开销放入邻接矩阵
|
||
if (row < c.m_nRouters) && (col < c.m_nRouters) {
|
||
c.adjMatrix[row][col] = linkCost
|
||
}
|
||
}
|
||
}
|
||
|
||
// todo 检查路由器A到路由器B的链路开销,若正向开销与反向开销不同,则两者均取较大值
|
||
|
||
return nil
|
||
}
|
||
|
||
//
|
||
// writeAdjMatrixLog
|
||
// @Description: 将格式化的邻接矩阵写入调试日志
|
||
// @receiver c 包含邻接矩阵数据的映射
|
||
// @param p
|
||
//
|
||
func (c *RoutingTableCalculator) writeAdjMatrixLog(p *sync.Map) {
|
||
// todo 输出调试信息,验证功能是否正常运行
|
||
}
|
||
|
||
//
|
||
// getNumOfLinkfromAdjMatrix
|
||
// @Description: 返回矩阵中一个路由器的邻接数(不包含其本身)
|
||
// @receiver c
|
||
// @param sRouter 计算邻接数的路由器
|
||
//
|
||
func (c *RoutingTableCalculator) getNumOfLinkfromAdjMatrix(sRouter int) int {
|
||
num := 0
|
||
for i := 0; i < c.m_nRouters; i++ {
|
||
if (c.adjMatrix[sRouter][i] != NON_ADJACENT_COST) && (i != sRouter) {
|
||
num++
|
||
}
|
||
}
|
||
return num
|
||
}
|
||
|
||
//
|
||
// freeAdjMatrix
|
||
// @Description: 释放内存
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) freeAdjMatrix() {
|
||
c.adjMatrix = [][]uint64{}
|
||
}
|
||
|
||
//
|
||
// adjustAdMatrix
|
||
// @Description: 在邻接矩阵中调整链路成本。除要更改的链路外,该源路由器的其它链路全部设置为不可达
|
||
// @receiver c
|
||
// @param source 要调整其邻接的源路由器
|
||
// @param link 要调整的源的邻接
|
||
// @param linkCost 更改为的成本。
|
||
//
|
||
func (c *RoutingTableCalculator) adjustAdMatrix(source int, link int, linkCost uint64) {
|
||
for i := 0; i < c.m_nRouters; i++ {
|
||
if i == link {
|
||
c.adjMatrix[source][i] = linkCost
|
||
} else {
|
||
c.adjMatrix[source][i] = NON_ADJACENT_COST
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// getLinksFromAdjMatrix
|
||
// @Description: 用一些路由器的链路成本填充临时变量
|
||
// 获取一些路由器的邻接和链路开销的稀疏列表。
|
||
// 由于这是稀疏的,这意味着在生成这些数组时,如果矩阵中i处没有邻接,
|
||
// 这些临时变量将不会在i处包含非邻接代价(NON_ADJACENT_COST,-12345),而是包含下一个有效邻接的值。
|
||
// @receiver c
|
||
// @param links 链接映射号的一个整数数组
|
||
// @param linkCosts 存储链路开销的一个双指针数组
|
||
// @param source 被调整值的路由器
|
||
//
|
||
func (c *RoutingTableCalculator) getLinksFromAdjMatrix(source int) {
|
||
index := 0
|
||
for i := 0; i < c.m_nRouters; i++ {
|
||
if (c.adjMatrix[source][i] != NON_ADJACENT_COST) && (i != source) {
|
||
c.links[index] = i
|
||
c.linkCosts[index] = c.adjMatrix[source][i]
|
||
index++
|
||
}
|
||
}
|
||
}
|
||
|
||
//
|
||
// allocateLinks
|
||
// @Description: 分配一个足以容纳多路径计算临时值的数组
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) allocateLinks() {
|
||
c.links = make([]int, c.vNoLink)
|
||
}
|
||
|
||
//
|
||
// allocateLinkCosts
|
||
// @Description: 分配内存
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) allocateLinkCosts() {
|
||
c.linkCosts = make([]uint64, c.vNoLink)
|
||
}
|
||
|
||
//
|
||
// freeLinks
|
||
// @Description: 释放内存
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) freeLinks() {
|
||
c.links = []int{}
|
||
}
|
||
|
||
//
|
||
// freeLinksCosts
|
||
// @Description: 释放内存
|
||
// @receiver c
|
||
//
|
||
func (c *RoutingTableCalculator) freeLinksCosts() {
|
||
c.linkCosts = []uint64{}
|
||
}
|
||
|
||
//
|
||
// setNoLink
|
||
// @Description: 设置链路数,即多路径中的“多”所代指的个数
|
||
// @receiver c
|
||
// @param nl
|
||
//
|
||
func (c *RoutingTableCalculator) setNoLink(nl int) {
|
||
c.vNoLink = nl
|
||
}
|