writting logicface: LogicFaceICN

This commit is contained in:
free will
2021-04-15 15:59:34 +08:00
parent fb469d20ac
commit 02678e8cfe
12 changed files with 456 additions and 10 deletions
+16 -10
View File
@@ -2,6 +2,7 @@ package encoding;
import component.CanBePrefix;
import component.ComponentException;
import mgmt.MgmtException;
import packet.PacketException;
/*
@@ -46,18 +47,23 @@ public class SelfEncodingBase {
* @param iEncodingAble
* @return
*/
public Block selfWireEncode(IEncodingAble iEncodingAble) throws EncoderException, BlockException, ComponentException, PacketException {
public Block selfWireEncode(IEncodingAble iEncodingAble) throws EncoderException, BlockException, ComponentException, PacketException{
// this.setiEncodingAble(iEncodingAble);
if((this.rawBlock!=null)&&this.rawBlock.isValid()){
return this.rawBlock;
}
try {
if ((this.rawBlock != null) && this.rawBlock.isValid()) {
return this.rawBlock;
}
Block block=easyEncoder(iEncodingAble);
if(block==null){
return null;
Block block = null;
block = easyEncoder(iEncodingAble);
if (block == null) {
return null;
}
this.rawBlock = block;
return block;
} catch (MgmtException e) {
throw new PacketException(""+e.getMessage());
}
this.rawBlock=block;
return block;
}
/**
@@ -66,7 +72,7 @@ public class SelfEncodingBase {
* @param iEncodingAble
* @return
*/
private Block easyEncoder(IEncodingAble iEncodingAble) throws PacketException, ComponentException, EncoderException, BlockException {
private Block easyEncoder(IEncodingAble iEncodingAble) throws PacketException, ComponentException, EncoderException, BlockException, MgmtException {
Encoder encoder=new Encoder();
// 首先测量目标 TLV 的大小
+236
View File
@@ -0,0 +1,236 @@
package logicface;
import component.ComponentException;
import component.Identifier;
import component.IdentifierWrapper;
import encoding.TLV;
import encoding.VlIntException;
import packet.*;
import util.CallbackFunction;
import util.ConcurrentHelper;
import util.TimeHelper;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.concurrent.locks.Lock;
/*
* @Author: Wang Feng
* @Description: 内容中心网络类型的 LogicFace 类
* @Version: 1.0.0
* @Date: 14:09 2021/4/14
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class LogicFaceICN extends LogicFace {
public Timer timer; // 定时器,在processEvent函数中就被设置成很大的值
public long recentExpireTime; // 最近将要超时的时间戳
public Map<String, PITEntry> mPit; // PIT表
public Lock timeoutEventHeapLock; // 锁, mpit 、timeoutEventHeap、recentExpireTime
public TimeoutEventHeap timeoutEventHeap; // 超时事件堆, 以超时时间排序的最小堆
public Map<String, OnInterest> mFib;
/**
* 通过最长匹配原则查找FIB表,找到合适的兴趣包处理函数
* @param identifier
* @return
*/
public OnInterest lookUpFib(Identifier identifier) throws LogicFaceException {
try {
int idComponentN = identifier.getComponents().length();
for (int i = idComponentN; i > 0; i--) {
Identifier prefix = identifier.getPrefix(i);
OnInterest fibEntry=this.mFib.get(prefix.toUri());
if(fibEntry!=null) {
return fibEntry;
}
}
return null;
} catch (ComponentException e) {
throw new LogicFaceException("LogicFaceICN.lookUpFib: "+e.getMessage());
}
}
/**
* 接收到 MINPacket 后调用 本函数,将 MINPacket 转为 Interest
* @param minPacket
*/
public void onReceiveInterest(MINPacket minPacket) throws LogicFaceException {
try {
Interest interest=new Interest().createInterestByMINPacket(minPacket);
if(interest==null){
return;
}
if(interest.nackHeader.isInitial()){
this.onReceiveNack(interest);
return;
}
IdentifierWrapper identifierWrapper=interest.minPacket.identifierField.getIdentifier(0);
PITEntry pitEntry=this.getPitEntryAndDelete(identifierWrapper.getIdentifier());
OnInterest oI=this.lookUpFib(identifierWrapper.getIdentifier());
if(oI!=null){
oI.onInterest(interest);
}
} catch (PacketException | ComponentException e) {
throw new LogicFaceException("LogicFaceICN.onReceiveInterest: "+e.getMessage());
}
}
/**
* 通过名称查询PIT表项,并在PIT中删除该表项
* @param identifier
* @return
*/
private PITEntry getPitEntryAndDelete(Identifier identifier) throws LogicFaceException {
try {
this.timeoutEventHeapLock.lock(); // 加锁访问
PITEntry pitEntry = this.mPit.get(identifier.toUri());
if(pitEntry!=null){
this.mPit.remove(identifier.toUri());
}
this.timeoutEventHeapLock.unlock(); // 解锁
return pitEntry;
} catch (ComponentException e) {
throw new LogicFaceException("LogicFaceICN.getPitEntryAndDelete: "+e.getMessage());
}
}
/**
* 接收到 MINPacket 后调用 本函数,将 MINPacket 转为 Data 查询PIT表,调用相应的onData回调函数来处理数据包
* @param minPacket
*/
public void onReceiveData(MINPacket minPacket) throws LogicFaceException {
try {
Data data=new Data().createDataByMINPacket(minPacket);
if(data==null){
return;
}
IdentifierWrapper identifierWrapper=data.minPacket.identifierField.getIdentifier(0);
PITEntry pitEntry = this.getPitEntryAndDelete(identifierWrapper.getIdentifier());
if(pitEntry==null){
return;
}
pitEntry.onData(pitEntry.interest,data);
} catch (PacketException | ComponentException e) {
throw new LogicFaceException("LogicFaceICN.onReceiveData: "+e.getMessage());
}
}
/**
* 用 onReceiveInterest 调用 如果兴趣包是 NACK,则调用该函数处理NACK包。
* // 用函数查找并删除PIT表项,并使用表项中记录的相应的onNack函数处理NACK包
* @param interest
*/
public void onReceiveNack(Interest interest) throws LogicFaceException {
try {
Nack nack=new Nack().createNackByInterest(interest);
if(nack==null){
return;
}
IdentifierWrapper identifierWrapper=nack.interest.minPacket.identifierField.getIdentifier(0);
PITEntry pitEntry = this.getPitEntryAndDelete(identifierWrapper.getIdentifier());
if(pitEntry==null){
return;
}
pitEntry.onNack(pitEntry.interest,nack);
} catch (ComponentException e) {
throw new LogicFaceException("LogicFaceICN.onReceiveNack: "+e.getMessage());
}
}
/**
* 处理超时事件,由 detectTimeout 调用 。 detectTimeout是由 timer定时器根据用户的设置定时触发的。
* // (1)每次发出一个兴趣包,会产生一个定时事件,放入超时事件堆 timeoutEventHeap
* // 2)如果超时时事放入timeoutEventHeap后,timeoutEventHeap 数组头的超时事件的超时时间 小于 最近即将发生的超时事
* // 件时间 recentExpireTime
* // 则将 timer 超时时间重新设置为 timeoutEventHeap 数组头的超时事件的超时时间 ,
* // recentExpireTime 也设置为timeoutEventHeap 数组头的超时事件的超时时间。 这个操作是 tryResetTimer 函数做的
* // 本函数的功能是:
* // 1)循环判断,如果timeoutEventHeap中还有事件,且 堆顶 的事件超时时间小于当前时间,则将事件从堆中弹出。
* // (2)通过弹出事件的键值在PIT表中查PIT表项,如果PIT表项存在,再判断PIT表项记录的超时时间是否确实小于等于当前时间 ;
* // (3)如果PIT表项记录的超时时间确实小于等于当前时间,则调用PIT表项中的超时回调函数onTimeout,
* // (4)如果PIT表项记录的超时时间大小当前时间,则重新设置timeEvent的超时时间为PIT表项的超时时间,
* // 并把timeEvent重新放回timeoutEventHeap中
* // 5)循环处理结果后,如果timeoutEventHeap还有元素,则将定时器超时时间和recentExpireTime变量设置成堆顶事件的超时时间
* // 6)如果timeoutEventHeap没元素了,则将定时器超时时间和recentExpireTime变量设置成一个比较大的值
*/
private void dealWithTimeout(){
long currentTime= TimeHelper.getTimestampMS();
this.timeoutEventHeapLock.lock();
while((this.timeoutEventHeap.len()>0)&&(this.timeoutEventHeap.get(0).timeoutTime<=currentTime)){
TimeoutEvent timeEvent=timeoutEventHeap.pop();
PITEntry pitEntry=this.mPit.get(timeEvent.key);
if(pitEntry!=null){
if(pitEntry.expireTime<=currentTime){
pitEntry.onTimeOut(pitEntry.interest);
this.mPit.remove(timeEvent.key);
}else{
timeEvent.timeoutTime=pitEntry.expireTime;
timeoutEventHeap.push(timeEvent);
}
}
}
if(this.timeoutEventHeap.len()>0){
// this.timer. todo: 什么鬼???
this.recentExpireTime=this.timeoutEventHeap.get(0).timeoutTime;
}else{
// this.timer. todo: 什么鬼???
this.recentExpireTime=currentTime+500000;
}
this.timeoutEventHeapLock.unlock();
}
/**
* 等待 timer超时,触发调用dealWithTimeout函数
*/
private void detectTimeout(){
while (true){
// this.timer.C // todo: 啥玩意儿啊??
this.dealWithTimeout();
}
}
/**
* 在 processEvent之前先初始化一些东西主要 包括初始化PIT表,和将定时器启动起来
*/
public void initBeforeProcessEvent(){
this.mPit=new HashMap<>();
this.timer=new Timer(); // todo: timer???
this.recentExpireTime=TimeHelper.getTimestampMS()+500000;
ConcurrentHelper.doConcurrent(() -> detectTimeout());
}
/**
* 不断调用ReceivePacket接收包,并按包类型进行区分后,调用相应的函数处理包
*/
public void doReceivePacket() throws LogicFaceException {
try {
while (true) {
MINPacket minPacket = this.receivePacket();
if(minPacket==null){
// todo: 日志记录一下
}
IdentifierWrapper identifier=minPacket.identifierField.getIdentifier(0);
if(identifier==null){
// todo: 日志记录一下
}
switch (identifier.getTlvType().getVlIntValue2Int()){
case TLV.TlvIdentifierContentInterest:
this.onReceiveInterest(minPacket);
case TLV.TlvIdentifierContentData:
this.onReceiveData(minPacket);
}
}
} catch (LogicFaceException | ComponentException | VlIntException e) {
throw new LogicFaceException("LogicFaceICN.doReceivePacket: "+e.getMessage());
}
}
/**
* 初始化一些变量,然后启动接收包阻塞线程
*/
public void processEvent(){
}
}
+15
View File
@@ -0,0 +1,15 @@
package logicface;
import packet.Data;
import packet.Interest;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 10:21 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public interface OnData {
void onData(Interest interest, Data data);
}
+14
View File
@@ -0,0 +1,14 @@
package logicface;
import packet.Interest;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 10:22 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public interface OnInterest {
void onInterest(Interest interest);
}
+15
View File
@@ -0,0 +1,15 @@
package logicface;
import packet.Interest;
import packet.Nack;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 10:23 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public interface OnNack {
void onNack(Interest interest, Nack nack);
}
+14
View File
@@ -0,0 +1,14 @@
package logicface;
import packet.Interest;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 10:22 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public interface OnTimeout {
void onTimeOut(Interest interest);
}
+20
View File
@@ -0,0 +1,20 @@
package logicface;
import packet.Data;
import packet.Interest;
import packet.Nack;
/*
* @Author: Wang Feng
* @Description: PIT表项,用于记录每个已发出的兴趣包
* @Version: 1.0.0
* @Date: 9:38 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public abstract class PITEntry implements OnData,OnTimeout,OnNack{
public Interest interest = new Interest(); // 兴趣包
public long expireTime = 0; // 本PIT表项的超时时间
// OnData oD = null; // 收到对应的数据包的处理函数
// OnTimeout oT = null; // 兴趣包超时的处理函数
// OnNack oN = null; // 兴趣包无路由的处理函数
}
+26
View File
@@ -0,0 +1,26 @@
package logicface;
/*
* @Author: Wang Feng
* @Description: 超时事件
* @Version: 1.0.0
* @Date: 11:59 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class TimeoutEvent {
public String key; // 重组器哈希表的key
public long timeoutTime; // 超时时间
public TimeoutEvent(){
}
public TimeoutEvent(String key,long timeoutTime){
this.key=key;
this.timeoutTime=timeoutTime;
}
public TimeoutEvent(TimeoutEvent timeoutEvent){
this.key=timeoutEvent.key;
this.timeoutTime=timeoutEvent.timeoutTime;
}
}
@@ -0,0 +1,51 @@
package logicface;
import java.util.LinkedList;
import java.util.List;
/*
* @Author: Wang Feng
* @Description: 超时事件堆
* TODO: Go语言中已经实现好了泛型heap,Java语言需要自己手动实现。要尽量兼顾功能性和高效性。
* @Version: 1.0.0
* @Date: 12:00 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class TimeoutEventHeap {
public List<TimeoutEvent> timeoutEvents=new LinkedList<>();
public boolean less(int i,int j){
return timeoutEvents.get(i).timeoutTime < timeoutEvents.get(j).timeoutTime;
}
public int len(){
return timeoutEvents.size();
}
public TimeoutEvent get(int index){
return timeoutEvents.get(index);
}
public void set(int index,TimeoutEvent timeoutEvent){
timeoutEvents.set(index,timeoutEvent);
// todo: 堆排序
}
public void swap(int i,int j){
TimeoutEvent cache=timeoutEvents.get(i);
timeoutEvents.set(i,timeoutEvents.get(j));
timeoutEvents.set(j,cache);
}
public void push(TimeoutEvent timeoutEvent){
timeoutEvents.add(timeoutEvent);
// todo: 堆排序
}
public TimeoutEvent pop(){
TimeoutEvent timeoutEvent=timeoutEvents.get(timeoutEvents.size()-1);
timeoutEvents.remove(timeoutEvents.size()-1);
// todo: 堆排序
return timeoutEvent;
}
}
+12
View File
@@ -0,0 +1,12 @@
package util;
/*
* @Author: Wang Feng
* @Description: 回调函数接口
* @Version: 1.0.0
* @Date: 15:10 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public interface CallbackFunction {
void callbackFunction();
}
+22
View File
@@ -0,0 +1,22 @@
package util;
import java.io.IOException;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 15:12 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class ConcurrentHelper {
public static void doConcurrent(CallbackFunction func){
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
func.callbackFunction();
}
});
thread.start();
}
}
+15
View File
@@ -0,0 +1,15 @@
package util;
/*
* @Author: Wang Feng
* @Description:
* @Version: 1.0.0
* @Date: 11:44 2021/4/15
* @Copyright: MIN-Group;国家重大科技基础设施——未来网络北大实验室;深圳市信息论与未来网络重点实验室
*/
public class TimeHelper {
// TODO: 后面需要实现这个函数。
public static long getTimestampMS(){
return 10000;
}
}