mirror of
https://gitee.com/willfree/min-dev-java.git
synced 2026-06-18 08:20:25 +08:00
writting logicface: LogicFaceICN
This commit is contained in:
@@ -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 的大小
|
||||
|
||||
@@ -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(){
|
||||
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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; // 兴趣包无路由的处理函数
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user