diff --git a/route/NamePrefixTableEntry.go b/route/NamePrefixTableEntry.go index daed3f9..cd251f4 100644 --- a/route/NamePrefixTableEntry.go +++ b/route/NamePrefixTableEntry.go @@ -9,7 +9,7 @@ package route import ( - "container/list" + common2 "minlib/common" "minlib/component" ) @@ -21,16 +21,153 @@ type NamePrefixTableEntry struct { // 名称前缀 m_namePrefix *component.Identifier - // 保存路由表池项列表。 + // 保存路由表池项的切片。切片真好用。 // 这是因为,由于支持网内缓存,一个名称前缀可能对应多个路由器标识符。 // 名称前缀标项,和路由表项,是多对多的关系。 - m_rteList list.List + m_rteList []*RoutingTablePoolEntry // 下一跳列表 NextHopList } -func (e *NamePrefixTableEntry) TestList() { - e.m_rteList.Init() - rtpe := new(RoutingTablePoolEntry) - e.m_rteList.PushBack(rtpe) +// +// GetNamePrefix +// @Description: 获取所表示的名称前缀 +// @receiver e +// @return *component.Identifier +// +func (e *NamePrefixTableEntry) GetNamePrefix() *component.Identifier { + return e.m_namePrefix +} + +// +// GetRteList +// @Description: 获取与该名称前缀所关联的路由表池项 +// @receiver e +// @return []*RoutingTablePoolEntry +// +func (e *NamePrefixTableEntry) GetRteList() []*RoutingTablePoolEntry { + return e.m_rteList +} + +// +// ResetRteListNextHop +// @Description: 重置播发此名称前缀的所有路由表项的下一跳列表。 +// @receiver e +// +func (e *NamePrefixTableEntry) ResetRteListNextHop() { + for i := 0; i < len(e.m_rteList); i++ { + e.m_rteList[i].Clear() + } +} + +// +// GetRteListSize +// @Description: 返回所关联的路由表池项的数目。即当前名称前缀被哪些路由器所拥有。 +// @receiver e +// @return int +// +func (e *NamePrefixTableEntry) GetRteListSize() int { + return len(e.m_rteList) +} + +// +// GetNexthopList +// @Description: 获取本名称前缀所关联的下一跳列表。 +// @receiver e +// @return []*NextHop +// +func (e *NamePrefixTableEntry) GetNexthopList() *NextHopList { + return &e.NextHopList +} + +// +// GenerateNhlfromRteList +// @Description: 收集此条目的路由条目播发的所有下一个跃点。 +// 其逻辑主要是将所有关联的路由表项的下一跳全部加进来。 +// @receiver e +// +func (e *NamePrefixTableEntry) GenerateNhlfromRteList() { + // 清空旧的下一跳列表 + e.NextHopList.Clear() + // 遍历关联的每个路由表条目 + for i := 0; i < len(e.m_rteList); i++ { + // 遍历路由表条目的下一跳列表 + for j := 0; j < e.m_rteList[i].NextHopList.Size(); j++ { + e.NextHopList.AddNextHop(e.m_rteList[i].nextHops[j]) + } + } +} + +// +// findRtpe +// @Description: 查找指定池条目 +// @receiver e +// @param rtpePtr +// @return int 没找到时返回-1 +// +func (e *NamePrefixTableEntry) findRtpe(rtpePtr *RoutingTablePoolEntry) int { + for i := 0; i < len(e.m_rteList); i++ { + if e.m_rteList[i].IsEqual(rtpePtr) { + return i + } + } + return -1 +} + +// +// deleteRtpe +// @Description: 删除指定索引位置的rtpe +// @receiver e +// @param index +// +func (e *NamePrefixTableEntry) deleteRtpe(index int) { + var tmpList []*RoutingTablePoolEntry + for i := 0; i < len(e.m_rteList); i++ { + if i != index { + tmpList = append(tmpList, e.m_rteList[i]) + } + } + e.m_rteList = tmpList +} + +// +// RemoveRoutingTableEntry +// @Description: 从该NPT条目中删除一个路由表条目 +// @receiver e +// @param rtpePtr +// @return uint64 使用刚刚删除的路由条目的NPT数。 +// +func (e *NamePrefixTableEntry) RemoveRoutingTableEntry(rtpePtr *RoutingTablePoolEntry) uint64 { + index := e.findRtpe(rtpePtr) + if index >= 0 { + // 该条目的使用数减一 + e.m_rteList[index].DecrementUseCount() + // 删除该条目与本名称前缀的关联 + // 1. 删掉:条目 -> 前缀 + delete(e.m_rteList[index].NamePrefixTableEntries, e.GetNamePrefix()) + // 2. 删掉:前缀 -> 条目 + e.deleteRtpe(index) + } else { + common2.LogError("Routing entry for: " + rtpePtr.GetDestination().ToUri() + + " not found in NPT entry: " + e.GetNamePrefix().ToUri()) + } + return rtpePtr.m_useCount +} + +// +// AddRoutingTableEntry +// @Description:将路由表池项添加到此NPT项的列表中 +// (提醒:每个RTPE都有下一个跃点列表)。它们用于计算此条目的整体下一跳列表。 +// @receiver e +// @param rtpePtr +// +func (e *NamePrefixTableEntry) AddRoutingTableEntry(rtpePtr *RoutingTablePoolEntry) { + index := e.findRtpe(rtpePtr) + // 先确定它是一个新的路由表条目 + if index < 0 { + // 其使用数加一 + rtpePtr.IncrementUseCount() + // 将其加入list + e.m_rteList = append(e.m_rteList, rtpePtr) + } } diff --git a/route/RoutingTablePoolEntry.go b/route/RoutingTablePoolEntry.go index 88feeb3..bd93736 100644 --- a/route/RoutingTablePoolEntry.go +++ b/route/RoutingTablePoolEntry.go @@ -59,6 +59,28 @@ func (pe *RoutingTablePoolEntry) InitDest(dest *component.Identifier, useCount u pe.m_useCount = useCount } +// +// IsEqual +// @Description: 判断两个路由表池条目是否相等 +// @receiver pe +// @param npe +// @return bool +// +func (pe *RoutingTablePoolEntry) IsEqual(npe *RoutingTablePoolEntry) bool { + if pe.GetDestination().ToUri() == npe.GetDestination().ToUri() && + pe.NextHopList.Size() == pe.NextHopList.Size() { + b := true + for i := 0; i < pe.NextHopList.Size(); i++ { + if pe.GetNextHops()[i].LogicFaceUri() != npe.GetNextHops()[i].LogicFaceUri() || + pe.GetNextHops()[i].RouteCost.RouteCost() != npe.GetNextHops()[i].RouteCost.RouteCost() { + b = false + } + } + return b + } + return false +} + // // GetUseCount // @Description: 获取使用数