147 lines
3.7 KiB
Java
147 lines
3.7 KiB
Java
package org.kne.cloud.network.congestion;
|
|
|
|
import java.io.Closeable;
|
|
import java.io.IOException;
|
|
import java.net.SocketException;
|
|
import java.net.SocketTimeoutException;
|
|
import java.util.Collection;
|
|
import java.util.Iterator;
|
|
import java.util.Map;
|
|
import java.util.UUID;
|
|
import java.util.Map.Entry;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.CountDownLatch;
|
|
import java.util.concurrent.atomic.AtomicInteger;
|
|
import java.util.concurrent.atomic.AtomicLong;
|
|
import java.util.concurrent.atomic.LongAdder;
|
|
import java.util.concurrent.locks.Condition;
|
|
import java.util.concurrent.locks.Lock;
|
|
import java.util.function.Consumer;
|
|
|
|
import org.kne.cloud.network.NetworkPacket;
|
|
import org.kne.cloud.network.ThreadTool;
|
|
import org.kne.cloud.network.ipv6.IPv6Packet;
|
|
import org.kne.cloud.network.klalb.DATATPacket;
|
|
import org.kne.cloud.network.klalb.SendItem;
|
|
import org.kne.cloud.network.kltp.KLTPPacket;
|
|
import org.kne.concurrent.ThreadParker;
|
|
|
|
public class ReceivePacketSlidingWindow<K, V extends NetworkPacket> implements Closeable, AutoCloseable{
|
|
private ThreadParker tp=new ThreadParker();
|
|
|
|
private Map<K,SendItem<V>> recvMap = new ConcurrentHashMap<K,SendItem<V>>();
|
|
private AtomicLong recvWindowUsed=new AtomicLong(0);
|
|
//private LongAdder recvWindowUsed=new LongAdder();
|
|
private long recvWindowSize;
|
|
private int headerCalibrate = 0;
|
|
|
|
private volatile boolean closed = false;
|
|
|
|
|
|
public ReceivePacketSlidingWindow(long recvWindowSize) {
|
|
super();
|
|
this.recvWindowSize = recvWindowSize;
|
|
}
|
|
|
|
public ReceivePacketSlidingWindow(long recvWindowSize, int headerCalibrate) {
|
|
super();
|
|
this.recvWindowSize = recvWindowSize;
|
|
this.headerCalibrate = headerCalibrate;
|
|
}
|
|
|
|
public void setHeaderCalibrate(int headerCalibrate) {
|
|
this.headerCalibrate = headerCalibrate;
|
|
}
|
|
|
|
public int getHeaderCalibrate() {
|
|
return headerCalibrate;
|
|
}
|
|
|
|
public void put(K sequence, V packet) {
|
|
SendItem<V> newitem = new SendItem<V>(packet,headerCalibrate);
|
|
SendItem<V> old = recvMap.putIfAbsent(sequence, newitem);
|
|
long dx=0;
|
|
if (old != null) {
|
|
dx=-old.getPacketLength() ;
|
|
}
|
|
recvWindowUsed.addAndGet(newitem.getPacketLength() +dx);
|
|
tp.unpark();
|
|
}
|
|
|
|
public V poll(K key) {
|
|
SendItem<V> dtp2 = recvMap.remove(key);
|
|
if (dtp2 != null) {
|
|
recvWindowUsed.addAndGet(-dtp2.getPacketLength());
|
|
return dtp2.getPacket();
|
|
}else {
|
|
return null;
|
|
}
|
|
}
|
|
public V take(K key) throws SocketException {
|
|
while(true) {
|
|
V val=poll(key);
|
|
if(val!=null) {
|
|
return val;
|
|
}
|
|
if(isClosed()) {
|
|
throw new SocketException("Receive window closed!");
|
|
}tp.parkNanos(1000000L);
|
|
}
|
|
}
|
|
|
|
public V take(K key,long timeoutNanos) throws SocketException, SocketTimeoutException {
|
|
long start=System.nanoTime();
|
|
while(true) {
|
|
if(System.nanoTime()-start>timeoutNanos) {
|
|
throw new SocketTimeoutException("Receive time out:"+(System.nanoTime()-start)+">"+timeoutNanos);
|
|
}
|
|
V val=poll(key);
|
|
if(val!=null) {
|
|
return val;
|
|
}
|
|
if(isClosed()) {
|
|
throw new SocketException("Receive window closed!");
|
|
}tp.parkNanos(1000000L);
|
|
}
|
|
}
|
|
|
|
public long getRecvWindowUsed() {
|
|
return recvWindowUsed.get();
|
|
}
|
|
|
|
public long getRecvWindowAvaliable() {
|
|
return Math.max(0, recvWindowSize-recvWindowUsed.get());
|
|
}
|
|
|
|
public Map<K, SendItem<V>> getRecvMap() {
|
|
return recvMap;
|
|
}
|
|
|
|
public int getWindowPacketCount() {
|
|
return recvMap.size();
|
|
}
|
|
|
|
public boolean isEmpty() {
|
|
return recvMap.isEmpty();
|
|
}
|
|
|
|
public boolean isClosed() {
|
|
return closed;
|
|
}
|
|
|
|
@Override
|
|
public void close() {
|
|
closed = true;
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return "ReceivePacketSlidingWindow [recvWindowUsed=" + recvWindowUsed + ", recvWindowSize=" + recvWindowSize
|
|
+ ", closed=" + closed + "]";
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|