coderplay
12/26/2012 - 2:12 AM

Java Map

Java Map

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
import java.util.Random;

import sun.misc.Unsafe;
import sun.nio.ch.DirectBuffer;

public class MappingTest {
  private static final int LONG_ARRAY_LENGTH = 10000000;
  private static final int LONG_ARRAY_OFFSET;

  private static final Unsafe unsafe;
  static {
    try {
      Field field = Unsafe.class.getDeclaredField("theUnsafe");
      field.setAccessible(true);
      unsafe = (Unsafe) field.get(null);
      LONG_ARRAY_OFFSET = unsafe.arrayBaseOffset(long[].class);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }

  public static void write(String filename, long[] longs) throws Exception {
    long start = System.nanoTime();
    DataOutputStream dos =
        new DataOutputStream(new BufferedOutputStream(new FileOutputStream(
            filename)));
    for (int i = 0; i < longs.length; i++) {
      dos.writeLong(longs[i]);
    }
    dos.close();
    System.out.println("write: " + (System.nanoTime() - start));
  }
  
  public static void read(String filename) throws Exception {
    long start = System.nanoTime();
    DataInputStream dis =
        new DataInputStream(new BufferedInputStream(new FileInputStream(
            filename)));
    
    long[] newLongs = new long[LONG_ARRAY_LENGTH];
    for (int i = 0; i < LONG_ARRAY_LENGTH; i++) {
      newLongs[i] = dis.readLong();
    }
    dis.close();
    System.out.println("read: " + (System.nanoTime() - start));
  }

  public static void writeMapped(String filename, long[] longs) throws Exception {
    long start = System.nanoTime();
    File file = new File(filename+".map");
    FileChannel channel = new RandomAccessFile(file, "rw").getChannel();
    int len = longs.length * Long.SIZE/8;
    ByteBuffer buf = channel.map(MapMode.READ_WRITE, 0L, len);

    long address = ((DirectBuffer) buf).address();
    unsafe.copyMemory(longs, LONG_ARRAY_OFFSET, null, address, len);
    channel.close();
    System.out.println("writeMapped: " + (System.nanoTime() - start));
  }
  

  public static void readMapped(String filename) throws Exception {
    long start = System.nanoTime();
    File file = new File(filename+".map");
    FileChannel channel = new RandomAccessFile(file, "r").getChannel();
    ByteBuffer buf = channel.map(MapMode.READ_ONLY, 0L, file.length());
    long address = ((DirectBuffer) buf).address();
    
    long[] newLongs = new long[LONG_ARRAY_LENGTH];
    int len = newLongs.length * Long.SIZE / 8;
    
    unsafe.copyMemory(null, address, newLongs, LONG_ARRAY_OFFSET, len);

    channel.close();
    System.out.println("readMapped: " + (System.nanoTime() - start));
//    for (int i = 0; i < LONG_ARRAY_LENGTH; i++) {
//      System.out.println("longs[" + i + "]" + newLongs[i]);
//    }
  }

  public static void main(String[] args) throws Exception {
    Random rnd = new Random();
    long[] longs = new long[LONG_ARRAY_LENGTH];
    for (int i = 0; i < LONG_ARRAY_LENGTH; i++) {
      longs[i] = i;
    }
    // bio
    write(".test", longs);
    read(".test");
    
    // 
    writeMapped(".test", longs);
    readMapped(".test");
  }

}