forked from KNEMC/KLALB
优化TUN性能
This commit is contained in:
@@ -9,9 +9,6 @@ import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
|
||||
|
||||
public class ByteBufferPool {
|
||||
private AtomicReferenceArray< ByteBuffer> rec;
|
||||
|
||||
@@ -258,7 +258,7 @@ public class FilterSocket extends Socket {
|
||||
// TODO 自动生成的方法存根
|
||||
return socket.isOutputShutdown();
|
||||
}
|
||||
|
||||
@SuppressWarnings("all")
|
||||
@Override
|
||||
public void setPerformancePreferences(int connectionTime, int latency, int bandwidth) {
|
||||
// TODO 自动生成的方法存根
|
||||
|
||||
@@ -8,7 +8,7 @@ import java.util.concurrent.locks.LockSupport;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.ThreadTool;
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.concurrent.YieldLock;
|
||||
import org.kne.opencl64.Releaser;
|
||||
|
||||
/**
|
||||
@@ -105,7 +105,7 @@ class ArrayListMessageBatcherReleaser<T> extends Releaser<ArrayListMessageBatche
|
||||
}
|
||||
class ArrayListMessageBatcher0<T> implements Runnable,MessageBatcher<T>{
|
||||
private ArrayList<T> messageList;
|
||||
private Lock lock=new SpinLock();
|
||||
private Lock lock=new YieldLock();
|
||||
private final int batchSize;
|
||||
private final long maxDelay;
|
||||
private Consumer<List<T>> consumer;
|
||||
|
||||
@@ -2,8 +2,7 @@ package org.kne.cloud.network.congestion;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.kne.cloud.network.monitor.DelaySampler;
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.concurrent.YieldLock;
|
||||
|
||||
public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCongestionAlgorithm {
|
||||
|
||||
@@ -32,7 +31,7 @@ public class Vegas2CongestionAlgorithm implements CongestionAlgorithm,DetnetCong
|
||||
private volatile long window2 = MIN_WINDOW;
|
||||
private volatile long maxwindow = 99999999999L;
|
||||
|
||||
private final SpinLock slock=new SpinLock();
|
||||
private final YieldLock slock=new YieldLock();
|
||||
|
||||
public Vegas2CongestionAlgorithm() {
|
||||
reset();
|
||||
|
||||
@@ -613,13 +613,16 @@ public class IPv6Packet extends NetworkPacket {
|
||||
*/
|
||||
@Override
|
||||
public void readFromChannel(ReadableByteChannel din, long length) throws IOException {
|
||||
IPv6header.limit(IPv6_HEADER_LENGTH);
|
||||
IPv6header.position(0);
|
||||
while (IPv6header.hasRemaining()) {
|
||||
if (din.read(IPv6header) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
IPv6header.limit(1);
|
||||
KNEChannels.readFully(din,IPv6header);
|
||||
int ver=getVersion();
|
||||
if(ver!=6){
|
||||
throw new StreamCorruptedException("Unsupported IPv"+ver);
|
||||
}
|
||||
|
||||
IPv6header.limit(IPv6_HEADER_LENGTH);
|
||||
KNEChannels.readFully(din,IPv6header);
|
||||
int payloadlength = getPayloadLength();
|
||||
int nextheader = getNextHeader();
|
||||
loop: while (true) {
|
||||
|
||||
@@ -2,8 +2,11 @@ package org.kne.cloud.network.ipv6;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.StreamCorruptedException;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
@@ -25,20 +28,21 @@ import org.kne.cloud.network.srv6.SRv6Router;
|
||||
import org.kne.cloud.network.tun.InetAddressRow;
|
||||
import org.kne.cloud.network.tun.TUNChannel;
|
||||
import org.kne.cloud.network.tun.TUNNetworkDevice;
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.concurrent.ThreadParker;
|
||||
import org.kne.concurrent.YieldLock;
|
||||
import org.kne.io.KNEChannels;
|
||||
|
||||
public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
||||
implements IPv6NetworkLink, Closeable, AutoCloseable {
|
||||
|
||||
|
||||
private TUNChannel channel;
|
||||
private TUNNetworkDevice tun;
|
||||
|
||||
private IPv6AddressGroup hostAddress;
|
||||
|
||||
private Thread tr;
|
||||
|
||||
private Lock slok = new SpinLock();
|
||||
private Lock slok = new YieldLock();
|
||||
|
||||
public IPv6TUNLoopbackNetworkLink(String name,IPv6AddressGroup hostAddress, int mtu, List<InetAddress> dns) throws IOException {
|
||||
super(true);
|
||||
@@ -60,27 +64,20 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
TUNChannel channel= tun.openSession();
|
||||
|
||||
channel = tun.openSession();
|
||||
Thread tb = new Thread(() -> {
|
||||
while (true) {
|
||||
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocateNative(65535);
|
||||
try {
|
||||
channel.read(tmp);
|
||||
tmp.flip();
|
||||
// System.out.println(tmp);
|
||||
if (IPv6Packet.getIPVersion(tmp.get(0)) == 6) {
|
||||
|
||||
ReadableByteChannel tmp = channel.readPacket();
|
||||
try {
|
||||
IPv6Packet ipp = new IPv6Packet();
|
||||
ipp.readFromChannel(KNEChannels.newReadableChannel(tmp), mtu);
|
||||
ipp.readFromChannel(tmp, mtu);
|
||||
|
||||
// NetworkPacket.databufferpool_65535.back(tmp);
|
||||
BiConsumer<IPv6NetworkLink, Supplier<IPv6Packet>> con = super.getReceiveConsumer();
|
||||
if (con != null) {
|
||||
if (ipp.getPayload().getProtocolNumber() == 6) {
|
||||
SRv6Router router = getSrv6Router();
|
||||
|
||||
if (router != null) {
|
||||
router.insertHopByHopHeader(ipp);
|
||||
}
|
||||
@@ -91,51 +88,22 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
||||
if (pid != null) {
|
||||
monitor.getUploadBandwidth().recordPacket(pid,1, (int) ipp.getTotalLength());
|
||||
}
|
||||
// ipp.setDisposeAfterSend(true);
|
||||
// ipp.getPayload().setDisposeAfterSend(true);
|
||||
return ipp;
|
||||
});
|
||||
} else {
|
||||
// ipp.dispose();
|
||||
}
|
||||
}catch(StreamCorruptedException e){
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}finally {
|
||||
tmp.close();
|
||||
}
|
||||
|
||||
} else {
|
||||
// NetworkPacket.databufferpool_65535.back(tmp);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// NetworkPacket.databufferpool_65535.back(tmp);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
});
|
||||
tb.setPriority(Thread.MAX_PRIORITY - 1);
|
||||
tb.start();
|
||||
tr = new Thread(() -> {
|
||||
while (true) {
|
||||
ByteBuffer tmp = sendQueue.poll();
|
||||
if (tmp != null) {
|
||||
|
||||
slok.lock();
|
||||
try {
|
||||
channel.write(tmp);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
slok.unlock();
|
||||
// NetworkPacket.databufferpool_65535.back(tmp);
|
||||
}
|
||||
} else {
|
||||
|
||||
LockSupport.parkNanos(1000000L);
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
tr.setPriority(Thread.MAX_PRIORITY - 1);
|
||||
tr.start();
|
||||
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
throw new IOException(e);
|
||||
@@ -143,8 +111,6 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
||||
onOnlineStateUpdate();
|
||||
}
|
||||
|
||||
private LinkedBlockingQueue<ByteBuffer> sendQueue = new LinkedBlockingQueue<ByteBuffer>();
|
||||
|
||||
private SpeedAndTrafficMonitorDataImpl monitor;
|
||||
|
||||
@Override
|
||||
@@ -192,17 +158,20 @@ public class IPv6TUNLoopbackNetworkLink extends AbstractIPv6NetworkLink
|
||||
}
|
||||
|
||||
private void sendPacket0(IPv6Packet pack, KLALBOAMHopByHopTLV oamtlv, DetNetSRv6TLV detNet) throws IOException {
|
||||
|
||||
|
||||
ByteBuffer tmp = NetworkPacket.bufferAllocator.allocate(65535);
|
||||
pack.writeToChannel(KNEChannels.newWritableChannel(tmp));
|
||||
WritableByteChannel wp = null;
|
||||
slok.lock();
|
||||
try {
|
||||
wp= channel.writePacket();
|
||||
pack.writeToChannel(wp);
|
||||
UUID pid = pack.getPacketID();
|
||||
if (pid != null) {
|
||||
monitor.getUploadBandwidth().recordPacket(pid, 1,(int) pack.getTotalLength());
|
||||
monitor.getUploadBandwidth().recordPacket(pid, 1, (int) pack.getTotalLength());
|
||||
}
|
||||
tmp.flip();
|
||||
sendQueue.add(tmp);
|
||||
LockSupport.unpark(tr);
|
||||
}finally {
|
||||
if(wp!=null)
|
||||
wp.close();
|
||||
slok.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -41,8 +41,8 @@ import org.kne.cloud.network.monitor.LinkStatus;
|
||||
import org.kne.cloud.network.monitor.SpeedAndTrafficAndDelayMonitorDataImpl;
|
||||
import org.kne.cloud.network.perf.TESTNPacket;
|
||||
import org.kne.cloud.network.te.BandwidthDistributer;
|
||||
import org.kne.concurrent.SpinLock;
|
||||
import org.kne.concurrent.ThreadParker;
|
||||
import org.kne.concurrent.YieldLock;
|
||||
import org.kne.math.Long128;
|
||||
|
||||
public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implements ControlledIPv6NetworkLink {
|
||||
@@ -192,7 +192,7 @@ public class KLALBRemoteLink extends AbstractControlledIPv6NetworkLink implement
|
||||
private volatile long time = System.nanoTime();
|
||||
private volatile long pingInterval = 100000000L;
|
||||
|
||||
private Lock sendLock=new SpinLock();
|
||||
private Lock sendLock=new YieldLock();
|
||||
|
||||
private boolean checkPingTime() {
|
||||
long cu = System.nanoTime();
|
||||
|
||||
@@ -569,13 +569,13 @@ public class GraphPanel extends JPanel {
|
||||
double x_4 = ex - arrXY_2[0]; // (x4,y4)是第二端点
|
||||
double y_4 = ey - arrXY_2[1];
|
||||
|
||||
Double X3 = new Double(x_3);
|
||||
Double X3 = Double.valueOf(x_3);
|
||||
x3 = X3.intValue();
|
||||
Double Y3 = new Double(y_3);
|
||||
Double Y3 = Double.valueOf(y_3);
|
||||
y3 = Y3.intValue();
|
||||
Double X4 = new Double(x_4);
|
||||
Double X4 = Double.valueOf(x_4);
|
||||
x4 = X4.intValue();
|
||||
Double Y4 = new Double(y_4);
|
||||
Double Y4 =Double.valueOf(y_4);
|
||||
y4 = Y4.intValue();
|
||||
// 画线
|
||||
g2.drawLine(sx, sy, ex, ey);
|
||||
|
||||
@@ -82,7 +82,7 @@ public class KLTPOutputStream extends OutputStream implements KLTPPacketConsumer
|
||||
|
||||
|
||||
|
||||
private Lock olock=new SpinLock();
|
||||
private Lock olock=new YieldLock();
|
||||
|
||||
private volatile boolean autoFlush=true;
|
||||
@Override
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
package org.kne.debug;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
import java.util.Set;
|
||||
final class Int implements Comparable<Int>,Cloneable {
|
||||
public int value;
|
||||
|
||||
public Int(int value) {
|
||||
super();
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() throws CloneNotSupportedException {
|
||||
// TODO �Զ����ɵķ������
|
||||
return super.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Int other = (Int) obj;
|
||||
if (value != other.value)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new Integer(value).toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Int o) {
|
||||
|
||||
return o.value-value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
public class Debuger extends Thread {
|
||||
Map <List<StackTraceElement>,Object[]>md=new HashMap<List<StackTraceElement>,Object[]>();
|
||||
@Override
|
||||
public void run() {
|
||||
while(true){
|
||||
for(int iz=0;iz<100;iz++){
|
||||
Map<Thread, StackTraceElement[]> m=Thread.getAllStackTraces();
|
||||
Set<Entry<Thread, StackTraceElement[]>> s=m.entrySet();
|
||||
Iterator<Entry<Thread, StackTraceElement[]>> i=s.iterator();
|
||||
while(i.hasNext()){
|
||||
Entry<Thread, StackTraceElement[]>elements =i.next();
|
||||
StackTraceElement[]value=elements.getValue();
|
||||
List<StackTraceElement> l=new ArrayList<StackTraceElement>(value.length);
|
||||
for (int j = 0; j < value.length; j++) {
|
||||
l.add(value[j]);
|
||||
}
|
||||
if(!l.isEmpty())
|
||||
if(md.containsKey(l)){
|
||||
((Int)md.get(l)[0]).value++;
|
||||
}else{
|
||||
md.put(l,new Object[]{new Int(1),elements.getKey()} );
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ArrayList<Entry<List<StackTraceElement>, Object[]>> tmp=new ArrayList();
|
||||
Set<Entry<List<StackTraceElement>, Object[]>> sn=md.entrySet();
|
||||
Iterator<Entry<List<StackTraceElement>, Object[]>> in=sn.iterator();
|
||||
while(in.hasNext()){
|
||||
Entry<List<StackTraceElement>, Object[]>elements =in.next();
|
||||
|
||||
tmp.add(elements);
|
||||
}
|
||||
tmp.sort(new Comparator<Entry<List<StackTraceElement>, Object[]>>() {
|
||||
|
||||
@Override
|
||||
public int compare(Entry<List<StackTraceElement>, Object[]> o1,
|
||||
Entry<List<StackTraceElement>, Object[]> o2) {
|
||||
|
||||
return ((Int)o2.getValue()[0]).value-((Int)o1.getValue()[0]).value;
|
||||
}
|
||||
});
|
||||
for(int d=0;d<tmp.size();d++){
|
||||
|
||||
Entry<List<StackTraceElement>, Object[]>elements=tmp.get(d);
|
||||
/*if(((Thread)(elements.getValue()[1])).getName().startsWith("SocketBridge A->B")){
|
||||
|
||||
}else{
|
||||
continue;
|
||||
}*/
|
||||
List<StackTraceElement> k=elements.getKey();
|
||||
StringBuilder sb=new StringBuilder();
|
||||
for(int d2=0;d2<k.size();d2++){
|
||||
sb.append(' ');sb.append(k.get(d2));
|
||||
}
|
||||
System.err.println(elements.getValue()[0]+":"+elements.getValue()[1]+"="+sb);
|
||||
}
|
||||
System.err.println("--------------------------------------------------------------------------------------------------------------------");
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {
|
||||
// TODO �Զ����ɵ� catch ��
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package org.kne.debug;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class TimeDebugger {
|
||||
private static final ExecutorService exct=Executors.newSingleThreadExecutor();
|
||||
private Map<String,Long> timeMap=new LinkedHashMap<String,Long>();
|
||||
private Lock timeLock=new ReentrantLock();
|
||||
long tmp=-1;
|
||||
|
||||
public void putTime(String name){
|
||||
timeLock.lock();
|
||||
try{
|
||||
long v=System.nanoTime();
|
||||
if(tmp==-1){
|
||||
timeMap.put(name, 0l);
|
||||
}else{
|
||||
timeMap.put(name, v-tmp);
|
||||
}
|
||||
tmp=v;
|
||||
}finally {
|
||||
timeLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, Long> getTimeMap() {
|
||||
return timeMap;
|
||||
}
|
||||
|
||||
public void print(){
|
||||
exct.execute(()->{
|
||||
timeLock.lock();
|
||||
|
||||
try{
|
||||
StringBuilder sbdr=new StringBuilder();
|
||||
sbdr.append('{');
|
||||
for (Iterator<Entry<String, Long>> iterator = timeMap.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<String, Long> type = (Entry<String, Long>) iterator.next();
|
||||
sbdr.append(type.getKey()).append('=').append(type.getValue());
|
||||
if(iterator.hasNext()) {
|
||||
sbdr.append(',');
|
||||
}
|
||||
}
|
||||
sbdr.append("}(ns)");
|
||||
System.out.println(sbdr.toString());
|
||||
}finally {
|
||||
timeLock.unlock();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void printWithTimeFilter(long nanos){
|
||||
exct.execute(()->{
|
||||
boolean b=false;
|
||||
timeLock.lock();
|
||||
|
||||
try{
|
||||
StringBuilder sbdr=new StringBuilder();
|
||||
sbdr.append('{');
|
||||
for (Iterator<Entry<String, Long>> iterator = timeMap.entrySet().iterator(); iterator.hasNext();) {
|
||||
Entry<String, Long> type = (Entry<String, Long>) iterator.next();
|
||||
if(type.getValue()>=nanos) {
|
||||
b=true;
|
||||
}
|
||||
sbdr.append(type.getKey()).append('=').append(type.getValue());
|
||||
if(iterator.hasNext()) {
|
||||
sbdr.append(',');
|
||||
}
|
||||
}
|
||||
sbdr.append("}(ns)");
|
||||
if(b)
|
||||
System.out.println(sbdr.toString());
|
||||
}finally {
|
||||
timeLock.unlock();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,42 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class AddInputStream extends InputStream {
|
||||
|
||||
volatile byte out = 0;
|
||||
private InputStream in;
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
int read = in.read();
|
||||
if (read==-1) {
|
||||
return -1;
|
||||
}
|
||||
out = (byte) (out+(byte) read);
|
||||
return out&0xff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
in.close();
|
||||
}
|
||||
|
||||
public AddInputStream(InputStream in) {
|
||||
super();
|
||||
this.in = in;
|
||||
}
|
||||
|
||||
public void read(byte[][] e) throws IOException {
|
||||
for (int y = 0; y<e.length; y++) {
|
||||
byte tmp[] = e[y];
|
||||
|
||||
for (int x = 0; x<tmp.length; x++) {
|
||||
tmp[x] = (byte) read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class AddOutputStream extends OutputStream {
|
||||
volatile byte out=0;
|
||||
private OutputStream o;
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
o.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void flush() throws IOException {
|
||||
|
||||
o.flush();
|
||||
}
|
||||
|
||||
public AddOutputStream(OutputStream o) {
|
||||
super();
|
||||
this.o = o;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
o.write((((byte)b)-out)&0xff);
|
||||
out=(byte) b;
|
||||
}
|
||||
public void write(byte[][]e) throws IOException{
|
||||
for (int y = 0; y < e.length; y++) {
|
||||
byte tmp[]=e[y];
|
||||
//System.out.println(Arrays.toString(tmp));
|
||||
for (int x = 0; x < tmp.length; x++) {
|
||||
write(tmp[x]&0xFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
public class ByteBufferManagement {
|
||||
//private
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
import java.util.zip.DataFormatException;
|
||||
import java.util.zip.Deflater;
|
||||
import java.util.zip.Inflater;
|
||||
import org.kne.debug.TimeDebugger;
|
||||
|
||||
public class Compress {
|
||||
static int n=0;
|
||||
public static ThreadPoolExecutor exf=(ThreadPoolExecutor) Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()*2, new ThreadFactory() {
|
||||
|
||||
@Override
|
||||
public Thread newThread(Runnable r) {
|
||||
Thread t=new Thread(r,"Compress #"+(n++));
|
||||
t.setDaemon(true);
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
public static Data compress(Data b) {
|
||||
|
||||
Deflater def=new Deflater(Deflater.BEST_COMPRESSION, true);
|
||||
def.setInput(b.b,b.off,b.len);
|
||||
def.finish();
|
||||
byte[]bo=new byte[(int) (b.len*1.1)+64];
|
||||
int vp=def.deflate(bo,4,bo.length-4);
|
||||
|
||||
def.end();
|
||||
int v=b.len;
|
||||
bo[0]=(byte) ((v >>> 24) & 0xFF);
|
||||
bo[1]=(byte) ((v >>> 16) & 0xFF);
|
||||
bo[2]=(byte) ((v >>> 8) & 0xFF);
|
||||
bo[3]=(byte) ((v >>> 0) & 0xFF);
|
||||
return new Data(bo,0,vp+4);
|
||||
}
|
||||
public static Data uncompress(Data b) throws IOException, DataFormatException {
|
||||
if(b.len<4){
|
||||
throw new EOFException("!!");
|
||||
}
|
||||
int ch1 =b.b[b.off+0]&0xff;
|
||||
int ch2 = b.b[b.off+1]&0xff;
|
||||
int ch3 =b. b[b.off+2]&0xff;
|
||||
int ch4 =b.b[b.off+3]&0xff;
|
||||
|
||||
int zix= ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + (ch4 << 0));
|
||||
|
||||
Inflater inf=new Inflater(true);
|
||||
inf.setInput(b.b, b.off+4, b.len-4);
|
||||
byte[]d=new byte[zix];
|
||||
int l=inf.inflate(d);
|
||||
inf.end();
|
||||
|
||||
return new Data(d,0,l);
|
||||
}
|
||||
private static class compresstask extends Task{
|
||||
volatile Data input,output;
|
||||
|
||||
public compresstask(Data input) {
|
||||
super();
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public Data getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTask() {
|
||||
output=compress(input);
|
||||
}
|
||||
|
||||
}
|
||||
public static void mulcomp(DataOutputStream dos,byte[]in, TimeDebugger dbg) throws IOException {
|
||||
ArrayList<Task> l=new ArrayList();
|
||||
int count =4;
|
||||
int sze=in.length/count;
|
||||
int y=in.length%count;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Task t=new compresstask(new Data(in,i*sze,sze));
|
||||
exf.execute(t);
|
||||
l.add(t);
|
||||
}
|
||||
Data tmp=null;
|
||||
if(y>0) {
|
||||
tmp=compress(new Data(in,count*sze,y));
|
||||
}
|
||||
dbg.putTime("compress");
|
||||
dos.writeInt(l.size()+(tmp==null?0:1));
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
compresstask n=(compresstask) l.get(i);
|
||||
n.waitfortask();
|
||||
Data g=n.getOutput();
|
||||
dos.writeInt(g.len);
|
||||
dos.write(g.b, g.off, g.len);
|
||||
|
||||
}
|
||||
|
||||
|
||||
if(tmp!=null) {
|
||||
dos.writeInt(tmp.len);
|
||||
dos.write(tmp.b, tmp.off, tmp.len);
|
||||
}
|
||||
}
|
||||
private static class uncompresstask extends Task{
|
||||
volatile Data input,output;
|
||||
|
||||
public uncompresstask(Data input) {
|
||||
super();
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public Data getOutput() {
|
||||
return output;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void runTask() {
|
||||
try {
|
||||
output=uncompress(input);
|
||||
} catch (IOException e) {
|
||||
// TODO �Զ����ɵ� catch ��
|
||||
e.printStackTrace();
|
||||
} catch (DataFormatException e) {
|
||||
// TODO �Զ����ɵ� catch ��
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
public static byte[] muluncomp(DataInputStream dis,TimeDebugger dbg) throws IOException, DataFormatException {
|
||||
ArrayList<Task> l=new ArrayList();
|
||||
ByteArrayOutputStream bod=new ByteArrayOutputStream(1024);
|
||||
int bc=dis.readInt();
|
||||
for(int x=0;x<bc;x++) {
|
||||
int s=dis.readInt();
|
||||
byte []input=new byte[s];
|
||||
int offset = 0;
|
||||
int numRead = 0;
|
||||
while (offset < input.length
|
||||
&& (numRead = dis.read(input, offset, input.length - offset)) >= 0) {
|
||||
offset += numRead;
|
||||
}
|
||||
Task tsk=new uncompresstask(new Data(input,0,input.length));
|
||||
exf.execute(tsk);
|
||||
l.add(tsk);
|
||||
|
||||
//Data rez=uncompress(new Data(input,0,input.length));
|
||||
|
||||
} dbg.putTime("read");
|
||||
for (int i = 0; i < l.size(); i++) {
|
||||
uncompresstask uct=(uncompresstask) l.get(i);
|
||||
uct.waitfortask();
|
||||
Data rez=uct.getOutput();
|
||||
bod.write(rez.b,rez.off,rez.len);
|
||||
}
|
||||
|
||||
|
||||
//rez.b.length=rez.off;
|
||||
return bod.toByteArray();
|
||||
}
|
||||
public static void main(String[] args) throws IOException, DataFormatException {
|
||||
String s="jjjjjjjjjjjjjjjjjjhjhjhm";
|
||||
byte[] ib=s.getBytes();
|
||||
Data i=new Data(ib,0,ib.length);
|
||||
Data o=compress(i);
|
||||
Data d=uncompress(o);
|
||||
System.out.println(o.len+" "+d.len);
|
||||
//for (int j = d.off; j < d.off+d.len; j++) {
|
||||
System.out.println(new String(d.b,d.off,d.len));
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
public class Data {
|
||||
byte[]b;
|
||||
int off,len;
|
||||
public Data(byte[] b, int off, int len) {
|
||||
super();
|
||||
this.b = b;
|
||||
this.off = off;
|
||||
this.len = len;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.nio.BufferOverflowException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ReadableByteChannel;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.channels.WritableByteChannel;
|
||||
|
||||
|
||||
public class KNEChannels {
|
||||
public static class ByteBufferWritableByteChannel implements WritableByteChannel{
|
||||
private ByteBuffer bbf;
|
||||
|
||||
public ByteBuffer getBbf() {
|
||||
return bbf;
|
||||
}
|
||||
public ByteBufferWritableByteChannel(ByteBuffer bbf) {
|
||||
this.bbf=bbf;
|
||||
}
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int write(ByteBuffer src) throws IOException {
|
||||
int opos=src.position();
|
||||
//System.out.println(bbf+" "+src);
|
||||
//FastLib .bufferPut(bbf,src);
|
||||
try {
|
||||
bbf.put(src);
|
||||
}catch(BufferOverflowException e) {
|
||||
throw new IOException(src.toString()+" "+bbf.toString(), e);
|
||||
}
|
||||
return src.position()-opos;
|
||||
}
|
||||
}
|
||||
public static WritableByteChannel newWritableChannel(ByteBuffer bbf) {
|
||||
return new ByteBufferWritableByteChannel(bbf);
|
||||
}
|
||||
public static class ByteBufferReadableByteChannel implements ReadableByteChannel {
|
||||
private ByteBuffer bbf;
|
||||
|
||||
public ByteBuffer getBbf() {
|
||||
return bbf;
|
||||
}
|
||||
public ByteBufferReadableByteChannel(ByteBuffer bbf) {
|
||||
this.bbf=bbf;
|
||||
}
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(ByteBuffer dst) throws IOException {
|
||||
if(!bbf.hasRemaining()) {
|
||||
return -1;
|
||||
}
|
||||
int lmtl=Math.min(bbf.remaining() ,dst.remaining());
|
||||
int olm=bbf.limit();
|
||||
bbf.limit(bbf.position()+lmtl);
|
||||
dst.put(bbf);
|
||||
bbf.limit(olm);
|
||||
return lmtl;
|
||||
}
|
||||
}
|
||||
public static ReadableByteChannel newReadableChannel(ByteBuffer bbf) {
|
||||
return new ByteBufferReadableByteChannel(bbf);
|
||||
}
|
||||
public static void readFully(ReadableByteChannel connectSocket, ByteBuffer szeRead) throws EOFException, IOException {
|
||||
while (szeRead.hasRemaining()) {
|
||||
if (connectSocket.read(szeRead) == -1) {
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.EOFException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class VarDataInputStream extends DataInputStream {
|
||||
|
||||
public VarDataInputStream(InputStream in) {
|
||||
super(in);
|
||||
|
||||
}
|
||||
public byte[] readPacketVarBytes() throws IOException {
|
||||
|
||||
int i;
|
||||
try {
|
||||
i=readVarInt();
|
||||
}catch(Exception e) {
|
||||
return null;
|
||||
}
|
||||
byte[]b=new byte[i];
|
||||
readFully(b);
|
||||
return b;
|
||||
}
|
||||
public byte[] readVarBytes() throws IOException {
|
||||
|
||||
int i=readVarInt();
|
||||
byte[]b=new byte[i];
|
||||
readFully(b);
|
||||
return b;
|
||||
}
|
||||
public String readVarUTF8() throws IOException {
|
||||
return new String(readVarBytes(), Charset.forName("UTF-8"));
|
||||
}
|
||||
int cache=0;
|
||||
public int readVarInt_addd()throws IOException {
|
||||
cache+=readVarInt();
|
||||
return cache;
|
||||
}
|
||||
public int readVarInt() throws IOException {
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
while (true) {
|
||||
byte b0 = this.readByte();
|
||||
i |= (b0 & 127) << j++ * 7;
|
||||
|
||||
if (j > 5) {
|
||||
throw new RuntimeException("VarInt too big");
|
||||
}
|
||||
|
||||
if ((b0 & 128) != 128) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
public long readVarLong() throws IOException {
|
||||
long i = 0L;
|
||||
int j = 0;
|
||||
|
||||
while (true) {
|
||||
byte b0 = this.readByte();
|
||||
i |= (long) (b0 & 127) << j++ * 7;
|
||||
|
||||
if (j > 10) {
|
||||
throw new RuntimeException("VarLong too big");
|
||||
}
|
||||
|
||||
if ((b0 & 128) != 128) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.kne.io;
|
||||
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
|
||||
public class VarDataOutputStream extends DataOutputStream {
|
||||
|
||||
public VarDataOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
int cache=0;
|
||||
public void writeVarInt_add(int input)throws IOException{
|
||||
writeVarInt (input-cache);
|
||||
cache=input;
|
||||
}
|
||||
public void writeVarBytes(byte[]b) throws IOException {
|
||||
writeVarInt(b.length);
|
||||
write(b);
|
||||
}
|
||||
public void writeVarUTF8(String str) throws IOException {
|
||||
writeVarBytes(str.getBytes(Charset.forName("UTF-8")));
|
||||
}
|
||||
public void writeVarInt(int input) throws IOException {
|
||||
while ((input & -128) != 0) {
|
||||
this.out.write(input & 127 | 128);
|
||||
input >>>= 7;
|
||||
}
|
||||
|
||||
this.out.write(input);
|
||||
}
|
||||
|
||||
|
||||
public void writeVarLong(long value) throws IOException {
|
||||
while ((value & -128L) != 0L) {
|
||||
this.writeByte((int) (value & 127L) | 128);
|
||||
value >>>= 7;
|
||||
}
|
||||
|
||||
this.writeByte((int) value);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user