Mercurial > hg4j
diff 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 |
line wrap: on
line diff
--- a/src/org/tmatesoft/hg/internal/RevlogCompressor.java Wed Jan 30 15:48:36 2013 +0100 +++ b/src/org/tmatesoft/hg/internal/RevlogCompressor.java Mon Feb 04 18:00:55 2013 +0100 @@ -17,9 +17,10 @@ package org.tmatesoft.hg.internal; import java.io.IOException; -import java.io.OutputStream; import java.util.zip.Deflater; -import java.util.zip.DeflaterOutputStream; + +import org.tmatesoft.hg.core.SessionContext; +import org.tmatesoft.hg.util.LogFacility.Severity; /** * @@ -27,45 +28,59 @@ * @author TMate Software Ltd. */ public class RevlogCompressor { + private final SessionContext ctx; private final Deflater zip; - private byte[] sourceData; - private int compressedLenEstimate; + private DataSerializer.DataSource sourceData; + private int compressedLen; - public RevlogCompressor() { + public RevlogCompressor(SessionContext sessionCtx) { + ctx = sessionCtx; zip = new Deflater(); } - public void reset(byte[] source) { + public void reset(DataSerializer.DataSource source) { sourceData = source; - compressedLenEstimate = -1; + compressedLen = -1; } - public int writeCompressedData(OutputStream out) throws IOException { + // out stream is not closed! + public int writeCompressedData(DataSerializer out) throws IOException { zip.reset(); - DeflaterOutputStream dos = new DeflaterOutputStream(out, zip, Math.min(2048, sourceData.length)); - dos.write(sourceData); - dos.finish(); + DeflaterDataSerializer dds = new DeflaterDataSerializer(out, zip, sourceData.serializeLength()); + sourceData.serialize(dds); + dds.finish(); return zip.getTotalOut(); } - public int getCompressedLengthEstimate() { - if (compressedLenEstimate != -1) { - return compressedLenEstimate; + public int getCompressedLength() { + if (compressedLen != -1) { + return compressedLen; } - zip.reset(); - int rv = 0; - // from DeflaterOutputStream: - byte[] buffer = new byte[Math.min(2048, sourceData.length)]; - for (int i = 0, stride = buffer.length; i < sourceData.length; i+= stride) { - zip.setInput(sourceData, i, Math.min(stride, sourceData.length - i)); - while (!zip.needsInput()) { - rv += zip.deflate(buffer, 0, buffer.length); - } - } - zip.finish(); - while (!zip.finished()) { - rv += zip.deflate(buffer, 0, buffer.length); - } - return compressedLenEstimate = rv; + Counter counter = new Counter(); + try { + compressedLen = writeCompressedData(counter); + assert counter.totalWritten == compressedLen; + return compressedLen; + } catch (IOException ex) { + // can't happen provided we write to our stream that does nothing but byte counting + ctx.getLog().dump(getClass(), Severity.Error, ex, "Failed estimating compressed length of revlog data"); + return counter.totalWritten; // use best known value so far + } + } + + private static class Counter extends DataSerializer { + public int totalWritten = 0; + + public void writeByte(byte... values) throws IOException { + totalWritten += values.length; + } + + public void writeInt(int... values) throws IOException { + totalWritten += 4 * values.length; + } + + public void write(byte[] data, int offset, int length) throws IOException { + totalWritten += length; + } } }