package com.meidusa.amoeba.benchmark; import java.io.File; import java.io.IOException; import java.io.RandomAccessFile; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel.MapMode; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.math.RandomUtils; import com.meidusa.amoeba.util.Initialisable; import com.meidusa.amoeba.util.InitialisationException; import com.meidusa.amoeba.util.MappedByteBufferUtil; import com.meidusa.amoeba.util.StringUtil; /** * �����ļ��ڴ�ӳ�䣬�ļ����������ݽ��ᵽ������ * �ļ����˹��� * @author Struct * */ public class FileLineRandomData implements RandomData<Object>,Initialisable{ private File file ; private RandomAccessFile raf = null; private int size; private String lineSplit; private boolean needSplit = true; private boolean closed = false; private MappedByteBuffer buffer = null; private String encoding = "gbk"; private int lineMaxLength = 10 * 1024; public int getLineMaxLength() { return lineMaxLength; } public void setLineMaxLength(int lineMaxLength) { this.lineMaxLength = lineMaxLength; } public String getEncoding() { return encoding; } public void setEncoding(String encoding) { this.encoding = encoding; } public boolean isNeedSplit() { return needSplit; } public void setNeedSplit(boolean needSplit) { this.needSplit = needSplit; } public String getLineSplit() { return lineSplit; } public void setLineSplit(String lineSplit) { if(StringUtil.isEmpty(lineSplit)){ lineSplit = null; }else{ this.lineSplit = lineSplit; } } public File getFile() { return file; } public void setFile(File file) { this.file = file; } private ThreadLocal<ByteBuffer> localBuffer = new ThreadLocal<ByteBuffer> (){ protected ByteBuffer initialValue() { return buffer.duplicate(); } }; private ThreadLocal<ByteBuffer> localTempBuffer = new ThreadLocal<ByteBuffer> (){ protected ByteBuffer initialValue() { return ByteBuffer.allocate(lineMaxLength); } }; @Override public void init() throws InitialisationException { try { raf = new RandomAccessFile(file,"r"); size = raf.length() > Integer.MAX_VALUE ? Integer.MAX_VALUE: Long.valueOf(raf.length()).intValue(); System.out.println("file size ="+size); buffer = raf.getChannel().map(MapMode.READ_ONLY, 0, size); buffer.load(); Runtime.getRuntime().addShutdownHook(new Thread(){ public void run(){ closed = true; MappedByteBufferUtil.unmap(buffer); try { raf.close(); } catch (IOException e) { } } }); } catch (IOException e) { throw new InitialisationException(e); } } @Override public Object nextData() { if(closed) throw new IllegalStateException("file closed.."); int position = RandomUtils.nextInt(size -1); ByteBuffer buffer = localBuffer.get(); goNextNewLineHead(buffer,position); String[] obj = null; String line = readLine(buffer); if(needSplit){ if(lineSplit == null){ obj = StringUtil.split(line); }else{ obj = StringUtil.split(line,lineSplit); } return obj; }else{ return line; } } private void goNextNewLineHead(ByteBuffer buffer,int position){ if(closed) throw new IllegalStateException("file closed.."); buffer.position(position); boolean eol = false; int c = -1; while (!eol) { switch (c = buffer.get()) { case -1: case '\n': eol = true; break; case '\r': eol = true; int cur = buffer.position(); if ((buffer.get()) != '\n') { buffer.position(cur); } break; } if(!eol){ if(position >0){ buffer.position(--position); }else{ eol = true; } } } } private final String readLine(ByteBuffer buffer) { if(closed) throw new IllegalStateException("file closed.."); ByteBuffer tempbuffer = localTempBuffer.get(); tempbuffer.position(0); tempbuffer.limit(tempbuffer.capacity()); byte c = -1; boolean eol = false; while (!eol) { switch (c = buffer.get()) { case -1: case '\n': eol = true; break; case '\r': eol = true; int cur = buffer.position(); if ((buffer.get()) != '\n') { buffer.position(cur); } break; default: tempbuffer.put(c); break; } } if ((c == -1) && (tempbuffer.position() == 0)) { return null; } tempbuffer.flip(); try { return new String(tempbuffer.array(),encoding); } catch (UnsupportedEncodingException e) { return new String(tempbuffer.array()); } } public static void main(String[] args) throws Exception{ final FileLineRandomData mapping = new FileLineRandomData(); mapping.setFile(new File("c:/role.txt")); mapping.init(); List<Thread> list = new ArrayList<Thread>(); long start = System.currentTimeMillis(); for(int j=0;j<1;j++){ Thread thread = new Thread(){ public void run(){ for(int i=0;i<1000;i++){ System.out.println(((String[])mapping.nextData())[1]); } } }; list.add(thread); thread.start(); } for(int i=0;i<list.size();i++){ list.get(i).join(); } System.out.println("time="+(System.currentTimeMillis()-start)); } }