forked from KNEMC/KLALB
重发数据包优先
This commit is contained in:
@@ -0,0 +1,188 @@
|
||||
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));
|
||||
//}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package org.kne.io;
|
||||
|
||||
public abstract class Task implements Runnable{
|
||||
private volatile boolean begin=false,end=false;
|
||||
private volatile Object t=new Object();
|
||||
@Override
|
||||
public void run() {
|
||||
begin=true;
|
||||
runTask();
|
||||
|
||||
end=true;
|
||||
if(t!=null) {
|
||||
synchronized(t) {
|
||||
t.notifyAll();
|
||||
}
|
||||
}
|
||||
}
|
||||
public void waitfortask() {
|
||||
synchronized(t){
|
||||
|
||||
try {
|
||||
while(!end) {
|
||||
t.wait(1);
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
|
||||
e.printStackTrace();
|
||||
}}
|
||||
}
|
||||
protected abstract void runTask();
|
||||
}
|
||||
Reference in New Issue
Block a user