mirror of
https://gitee.com/willfree/mlsr.git
synced 2026-06-11 08:39:34 +08:00
183 lines
4.3 KiB
Go
183 lines
4.3 KiB
Go
// Package route
|
|
// @Author: Wang Feng
|
|
// @Description:
|
|
// 参考博文:https://www.zhaoyanchang.com/detail/31.html
|
|
// @Version: 0.1.0
|
|
// @Date: 2022/5/10 15:26
|
|
// @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
|
|
//
|
|
|
|
package route
|
|
|
|
import (
|
|
"encoding/json"
|
|
"minlib/component"
|
|
"mlsr/lsa"
|
|
"strconv"
|
|
"sync"
|
|
)
|
|
|
|
//
|
|
// RouterMap
|
|
// @Description: 给每个路由器标识分配一个索引号
|
|
//
|
|
type RouterMap struct {
|
|
// 存储:路由器到索引值的映射
|
|
routerToNumberMap map[string]int
|
|
// 存储:索引值到路由器的映射
|
|
numberToRouterMap map[int]string
|
|
// 存储:路由器URI到其路由器标识的映射 => 相同URI的路由器标识被视为同一个路由器标识
|
|
uriToIdentifierMap map[string]*component.Identifier
|
|
|
|
// 初始值为0,每次加一递增
|
|
mappingIndex int
|
|
|
|
// 并发加锁
|
|
mapLock *sync.RWMutex
|
|
}
|
|
|
|
//
|
|
// ToString
|
|
// @Description: 转string,便于测试查看map的状态
|
|
// @receiver m
|
|
// @return string
|
|
//
|
|
func (m *RouterMap) ToString() string {
|
|
s := ""
|
|
s += "MappingIndex:" + strconv.Itoa(m.mappingIndex) + " "
|
|
// 第一个map
|
|
dataType, _ := json.Marshal(m.routerToNumberMap)
|
|
dataString := string(dataType)
|
|
s += dataString + " "
|
|
// 第二个map
|
|
dataType, _ = json.Marshal(m.numberToRouterMap)
|
|
dataString = string(dataType)
|
|
s += dataString + " "
|
|
return s
|
|
}
|
|
|
|
//
|
|
// Store
|
|
// @Description: 存入一个路由器标识
|
|
// @receiver m
|
|
// @param routerName
|
|
//
|
|
func (m *RouterMap) Store(routerName *component.Identifier) {
|
|
m.mapLock.Lock()
|
|
uri := routerName.ToUri()
|
|
_, ok := m.uriToIdentifierMap[uri]
|
|
if !ok {
|
|
// 如果不存在,则将其存入三张map
|
|
m.uriToIdentifierMap[uri] = routerName
|
|
m.routerToNumberMap[uri] = m.mappingIndex
|
|
m.numberToRouterMap[m.mappingIndex] = uri
|
|
m.mappingIndex++
|
|
}
|
|
m.mapLock.Unlock()
|
|
}
|
|
|
|
//
|
|
// CreateFromAdjLsdb
|
|
// @Description: 根据从LSDB中取出来的邻接LSA,进行RouterMap的生成
|
|
// @receiver m
|
|
// @param lsas
|
|
// @return error
|
|
//
|
|
func (m *RouterMap) CreateFromAdjLsdb(lsas []lsa.ILsa) error {
|
|
for i := 0; i < len(lsas); i++ {
|
|
// 1. 先将LSA解析为邻接LSA
|
|
adjLsa := (lsas[i]).(*lsa.AdjLsa)
|
|
// 2. 将每个邻接lsa的源路由,以及所有该源路由的邻接路由器,都加入到map中
|
|
m.Store(adjLsa.GetOriginRouter())
|
|
adjs := adjLsa.GetAdjList()
|
|
for j := 0; j < len(adjs); j++ {
|
|
m.Store(adjs[j].GetNeighborRouterIdentifier())
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
//
|
|
// Delete
|
|
// @Description: 删除一个路由器标识。在实际使用中用不到,故先小写其字母。
|
|
// @receiver m
|
|
// @param routerName
|
|
//
|
|
func (m *RouterMap) delete(routerName *component.Identifier) {
|
|
m.mapLock.Lock()
|
|
uri := routerName.ToUri()
|
|
value, ok := m.routerToNumberMap[uri]
|
|
if ok {
|
|
// 如果存在,则将其从三张map中删除
|
|
delete(m.uriToIdentifierMap, uri)
|
|
delete(m.routerToNumberMap, uri)
|
|
delete(m.numberToRouterMap, value)
|
|
}
|
|
m.mapLock.Unlock()
|
|
}
|
|
|
|
//
|
|
// GetRouterNameByMappingNo
|
|
// @Description: 根据索引获取路由器标识
|
|
// @receiver m
|
|
// @param index
|
|
// @return *component.Identifier
|
|
// @return bool
|
|
//
|
|
func (m *RouterMap) GetRouterNameByMappingNo(index int) (*component.Identifier, bool) {
|
|
m.mapLock.Lock()
|
|
defer m.mapLock.Unlock()
|
|
value, ok := m.numberToRouterMap[index]
|
|
if ok {
|
|
idenValue := m.uriToIdentifierMap[value]
|
|
return idenValue, true
|
|
}
|
|
return nil, false
|
|
}
|
|
|
|
//
|
|
// GetMappingNoByRouterName
|
|
// @Description: 根据标识获取索引
|
|
// @receiver m
|
|
// @param routerName
|
|
// @return int
|
|
// @return bool
|
|
//
|
|
func (m *RouterMap) GetMappingNoByRouterName(routerName *component.Identifier) (int, bool) {
|
|
m.mapLock.Lock()
|
|
defer m.mapLock.Unlock()
|
|
value, ok := m.routerToNumberMap[routerName.ToUri()]
|
|
return value, ok
|
|
}
|
|
|
|
//
|
|
// GetMapSize
|
|
// @Description: 获取路由器数目
|
|
// @receiver m
|
|
// @return int
|
|
//
|
|
func (m *RouterMap) GetMapSize() int {
|
|
m.Init()
|
|
return len(m.routerToNumberMap)
|
|
}
|
|
|
|
//
|
|
// Init
|
|
// @Description: 必须先执行该函数,以初始化RouterMap
|
|
// @receiver m*
|
|
//
|
|
func (m *RouterMap) Init() {
|
|
if m.uriToIdentifierMap == nil {
|
|
m.uriToIdentifierMap = make(map[string]*component.Identifier)
|
|
}
|
|
if m.routerToNumberMap == nil {
|
|
m.routerToNumberMap = make(map[string]int)
|
|
}
|
|
if m.numberToRouterMap == nil {
|
|
m.numberToRouterMap = make(map[int]string)
|
|
}
|
|
if m.mapLock == nil {
|
|
m.mapLock = new(sync.RWMutex)
|
|
}
|
|
}
|