Guest User

Untitled

a guest
Jul 6th, 2012
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.85 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.ArrayList;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.IOException;
  7. import java.nio.ByteBuffer;
  8. import java.nio.channels.FileChannel;
  9. import java.util.Random;
  10. import java.util.zip.DataFormatException;
  11. import java.util.zip.Deflater;
  12. import java.util.zip.Inflater;
  13.  
  14. public class Test {
  15. private static final int bucketSize = 1<<17;//in real world should not be const, but we bored horribly
  16. static final int zipLevel = 2;//feel free to experiement, higher compression (5+)is likely to be total waste
  17.  
  18.  
  19. static void writes(long[] a, File file, boolean sync) throws IOException{
  20. byte[] bucket = new byte[Math.min(bucketSize, Math.max(1<<13, Integer.highestOneBit(a.length >>3)))];//128KB bucket
  21. byte[] zipOut = new byte[bucket.length];
  22.  
  23. final FileOutputStream fout = new FileOutputStream(file);
  24. FileChannel channel = fout.getChannel();
  25. try{
  26.  
  27. ByteBuffer buf = ByteBuffer.wrap(bucket);
  28. //unfortunately java.util.zip doesn't support Direct Buffer - that would be the perfect fit
  29. ByteBuffer out = ByteBuffer.wrap(zipOut);
  30. out.putLong(a.length);//write length aka header
  31. if (a.length==0){
  32. doWrite(channel, out, 0);
  33. return;
  34. }
  35.  
  36. Deflater deflater = new Deflater(zipLevel, false);
  37. try{
  38. for (int i=0;i<a.length;){
  39. i = puts(a, buf, i);
  40. buf.flip();
  41. deflater.setInput(bucket, buf.position(), buf.limit());
  42.  
  43. if (i==a.length)
  44. deflater.finish();
  45.  
  46. //hacking and using bucket here is tempting since it's copied twice but well
  47. for (int n; (n= deflater.deflate(zipOut, out.position(), out.remaining()))>0;){
  48. doWrite(channel, out, n);
  49. }
  50. buf.clear();
  51. }
  52.  
  53. }finally{
  54. deflater.end();
  55. }
  56. }finally{
  57. if (sync)
  58. fout.getFD().sync();
  59. channel.close();
  60. }
  61. }
  62.  
  63. static long[] reads(File file) throws IOException, DataFormatException{
  64. FileChannel channel = new FileInputStream(file).getChannel();
  65. try{
  66. byte[] in = new byte[(int)Math.min(bucketSize, channel.size())];
  67. ByteBuffer buf = ByteBuffer.wrap(in);
  68. System.out.println("Read channel size: " + in.length);
  69. channel.read(buf);
  70. buf.flip();
  71. long[] a = new long[(int)buf.getLong()];
  72. System.out.println("Read length: " + a.length);
  73. if (a.length==0)
  74. return a;
  75. int i=0;
  76. byte[] inflated = new byte[Math.min(1<<17, a.length*8)];
  77. ByteBuffer longBuffer = ByteBuffer.wrap(inflated);
  78. Inflater inflater = new Inflater(false);
  79. try{
  80. do{
  81. if (!buf.hasRemaining()){
  82. buf.clear();
  83. channel.read(buf);
  84. buf.flip();
  85. }
  86. inflater.setInput(in, buf.position(), buf.remaining());
  87. buf.position(buf.position()+buf.remaining());//simulate all read
  88.  
  89. for (;;){
  90. int n = inflater.inflate(inflated,longBuffer.position(), longBuffer.remaining());
  91. if (n==0)
  92. break;
  93. longBuffer.position(longBuffer.position()+n).flip();
  94. for (;longBuffer.remaining()>7 && i<a.length;i++){//need at least 4 bytes to form an int
  95. a[i] = longBuffer.getLong();
  96. }
  97. longBuffer.compact();
  98. }
  99.  
  100. }while (channel.position()<channel.size() && i<a.length);
  101. }finally{
  102. inflater.end();
  103. }
  104. // System.out.printf("read ints: %d - channel.position:%d %n", i, channel.position());
  105. return a;
  106. }finally{
  107. channel.close();
  108. }
  109. }
  110.  
  111. private static void doWrite(FileChannel channel, ByteBuffer out, int n) throws IOException {
  112. out.position(out.position()+n).flip();
  113. while (out.hasRemaining())
  114. channel.write(out);
  115. out.clear();
  116. }
  117. private static int puts(long[] a, ByteBuffer buf, int i) {
  118. for (;buf.hasRemaining() && i<a.length;){
  119. buf.putLong(a[i++]);
  120. }
  121. return i;
  122. }
  123.  
  124.  
  125.  
  126.  
  127.  
  128. private static long[] generateRandom(int len){
  129. Random r = new Random(17);
  130. long[] n = new long [len];
  131. for (int i=0;i<len;i++){
  132. n[i]= r.nextBoolean()?0: r.nextInt(1<<23);//limit bounds to have any sensible compression
  133. }
  134. return n;
  135. }
  136. public static void main(String[] args) throws Throwable{
  137. File file = new File("xxx.xxx");
  138. long[] n = generateRandom(3000000); //{0,2,4,1,2,3};
  139. long start = System.nanoTime();
  140. writes(n, file, false);
  141. long elapsed = System.nanoTime() - start;//elapsed will be fairer if the sync is true
  142.  
  143. System.out.printf("File length: %d, for %d ints, ratio %.2f in %.2fms %n", file.length(), n.length, ((double)file.length())/8/n.length, java.math.BigDecimal.valueOf(elapsed, 6) );
  144.  
  145. long[] m = reads(file);
  146.  
  147. //compare, Arrays.equals doesn't return position, so it sucks/kinda
  148. for (int i=0; i<n.length; i++){
  149. if (m[i]!=n[i]){
  150. System.err.printf("Failed at %d%n",i);
  151. break;
  152. }
  153. }
  154. System.out.printf("All done!");
  155. };
  156.  
  157. }
Advertisement
Add Comment
Please, Sign In to add comment