Mercurial > jhg
comparison src/org/tmatesoft/hg/internal/RevlogCompressor.java @ 534:243202f1bda5
Commit: refactor revision creation code from clone command to work separately, fit into existing library structure
| author | Artem Tikhomirov <tikhomirov.artem@gmail.com> |
|---|---|
| date | Mon, 04 Feb 2013 18:00:55 +0100 |
| parents | 0f6fa88e2162 |
| children | 7c0d2ce340b8 |
comparison
equal
deleted
inserted
replaced
| 533:e6f72c9829a6 | 534:243202f1bda5 |
|---|---|
| 15 * contact TMate Software at support@hg4j.com | 15 * contact TMate Software at support@hg4j.com |
| 16 */ | 16 */ |
| 17 package org.tmatesoft.hg.internal; | 17 package org.tmatesoft.hg.internal; |
| 18 | 18 |
| 19 import java.io.IOException; | 19 import java.io.IOException; |
| 20 import java.io.OutputStream; | |
| 21 import java.util.zip.Deflater; | 20 import java.util.zip.Deflater; |
| 22 import java.util.zip.DeflaterOutputStream; | 21 |
| 22 import org.tmatesoft.hg.core.SessionContext; | |
| 23 import org.tmatesoft.hg.util.LogFacility.Severity; | |
| 23 | 24 |
| 24 /** | 25 /** |
| 25 * | 26 * |
| 26 * @author Artem Tikhomirov | 27 * @author Artem Tikhomirov |
| 27 * @author TMate Software Ltd. | 28 * @author TMate Software Ltd. |
| 28 */ | 29 */ |
| 29 public class RevlogCompressor { | 30 public class RevlogCompressor { |
| 31 private final SessionContext ctx; | |
| 30 private final Deflater zip; | 32 private final Deflater zip; |
| 31 private byte[] sourceData; | 33 private DataSerializer.DataSource sourceData; |
| 32 private int compressedLenEstimate; | 34 private int compressedLen; |
| 33 | 35 |
| 34 public RevlogCompressor() { | 36 public RevlogCompressor(SessionContext sessionCtx) { |
| 37 ctx = sessionCtx; | |
| 35 zip = new Deflater(); | 38 zip = new Deflater(); |
| 36 } | 39 } |
| 37 | 40 |
| 38 public void reset(byte[] source) { | 41 public void reset(DataSerializer.DataSource source) { |
| 39 sourceData = source; | 42 sourceData = source; |
| 40 compressedLenEstimate = -1; | 43 compressedLen = -1; |
| 41 } | 44 } |
| 42 | 45 |
| 43 public int writeCompressedData(OutputStream out) throws IOException { | 46 // out stream is not closed! |
| 47 public int writeCompressedData(DataSerializer out) throws IOException { | |
| 44 zip.reset(); | 48 zip.reset(); |
| 45 DeflaterOutputStream dos = new DeflaterOutputStream(out, zip, Math.min(2048, sourceData.length)); | 49 DeflaterDataSerializer dds = new DeflaterDataSerializer(out, zip, sourceData.serializeLength()); |
| 46 dos.write(sourceData); | 50 sourceData.serialize(dds); |
| 47 dos.finish(); | 51 dds.finish(); |
| 48 return zip.getTotalOut(); | 52 return zip.getTotalOut(); |
| 49 } | 53 } |
| 50 | 54 |
| 51 public int getCompressedLengthEstimate() { | 55 public int getCompressedLength() { |
| 52 if (compressedLenEstimate != -1) { | 56 if (compressedLen != -1) { |
| 53 return compressedLenEstimate; | 57 return compressedLen; |
| 54 } | 58 } |
| 55 zip.reset(); | 59 Counter counter = new Counter(); |
| 56 int rv = 0; | 60 try { |
| 57 // from DeflaterOutputStream: | 61 compressedLen = writeCompressedData(counter); |
| 58 byte[] buffer = new byte[Math.min(2048, sourceData.length)]; | 62 assert counter.totalWritten == compressedLen; |
| 59 for (int i = 0, stride = buffer.length; i < sourceData.length; i+= stride) { | 63 return compressedLen; |
| 60 zip.setInput(sourceData, i, Math.min(stride, sourceData.length - i)); | 64 } catch (IOException ex) { |
| 61 while (!zip.needsInput()) { | 65 // can't happen provided we write to our stream that does nothing but byte counting |
| 62 rv += zip.deflate(buffer, 0, buffer.length); | 66 ctx.getLog().dump(getClass(), Severity.Error, ex, "Failed estimating compressed length of revlog data"); |
| 63 } | 67 return counter.totalWritten; // use best known value so far |
| 64 } | 68 } |
| 65 zip.finish(); | 69 } |
| 66 while (!zip.finished()) { | 70 |
| 67 rv += zip.deflate(buffer, 0, buffer.length); | 71 private static class Counter extends DataSerializer { |
| 68 } | 72 public int totalWritten = 0; |
| 69 return compressedLenEstimate = rv; | 73 |
| 74 public void writeByte(byte... values) throws IOException { | |
| 75 totalWritten += values.length; | |
| 76 } | |
| 77 | |
| 78 public void writeInt(int... values) throws IOException { | |
| 79 totalWritten += 4 * values.length; | |
| 80 } | |
| 81 | |
| 82 public void write(byte[] data, int offset, int length) throws IOException { | |
| 83 totalWritten += length; | |
| 84 } | |
| 70 } | 85 } |
| 71 } | 86 } |
