KLALB 3.6.0开发一半的状态
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
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 + "]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user