Mercurial > hg4j
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 } |