Gitlab Community Edition Instance

Commit a2744151 authored by mhellka's avatar mhellka
Browse files

MultiDigest cleanup

parent 709049ff
......@@ -6,16 +6,24 @@ import java.io.InputStream;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Class to calculate multiple digests using different algorithms in one go.
*
* Hint: During tests, using parallel streams (three threads, 128k blocksize)
* had over 60% overhead while only increasing throughput by 20%.
*/
public class MultiDigest {
private final MessageDigest[] runningDigests;
private final Map<String, byte[]> results = new HashMap<>();
/* read buffer for InputStream inputs */
private static final int READ_BUFFER = 1024 * 64;
private final List<MessageDigest> runningDigests;
private final Map<String, byte[]> results;
long size = 0;
public MultiDigest(Collection<String> algorithms) {
......@@ -23,10 +31,11 @@ public class MultiDigest {
}
public MultiDigest(String... algorithms) {
runningDigests = new MessageDigest[algorithms.length];
results = new HashMap<>(algorithms.length);
runningDigests = new ArrayList<>(algorithms.length);
try {
for (int i = 0; i < algorithms.length; i++) {
runningDigests[i] = MessageDigest.getInstance(algorithms[i]);
for (String name : algorithms) {
runningDigests.add(MessageDigest.getInstance(name));
}
} catch (final NoSuchAlgorithmException e) {
throw new RuntimeException(e);
......@@ -34,39 +43,51 @@ public class MultiDigest {
}
public void reset() {
for (final MessageDigest d : runningDigests)
d.reset();
runningDigests.forEach(MessageDigest::reset);
results.clear();
size = 0;
}
public Map<String, byte[]> digest() {
if (results.isEmpty())
for (final MessageDigest d : runningDigests)
results.put(d.getAlgorithm(), d.digest());
if (results.isEmpty()) {
runningDigests.forEach(md -> results.put(md.getAlgorithm(), md.digest()));
}
return results;
}
public MultiDigest update(byte[] data, int skip, int limit) {
for (final MessageDigest d : runningDigests)
d.update(data, skip, limit);
size += Math.min(data.length - skip, limit);
int len = Math.min(data.length - skip, limit);
if (len <= 0)
return this;
runningDigests.forEach(md -> md.update(data, skip, len));
size += len;
return this;
}
public MultiDigest update(byte[] data) {
return update(data, 0, data.length);
public MultiDigest update(ByteBuffer buffer) {
if (buffer.remaining() <= 0)
return this;
runningDigests.forEach(md -> md.update(buffer.duplicate()));
size += buffer.remaining();
return this;
}
public MultiDigest update(byte b) {
for (final MessageDigest d : runningDigests)
d.update(b);
runningDigests.forEach(md -> md.update(b));
size += 1;
return this;
}
public MultiDigest update(byte[] data) {
return update(data, 0, data.length);
}
public MultiDigest update(InputStream stream) throws IOException {
final byte[] buffer = new byte[1024 * 64];
final byte[] buffer = new byte[READ_BUFFER];
int bytes;
while ((bytes = stream.read(buffer)) > -1) {
update(buffer, 0, bytes);
......@@ -74,14 +95,6 @@ public class MultiDigest {
return this;
}
public MultiDigest update(ByteBuffer buffer) {
for (final MessageDigest d : runningDigests) {
d.update(buffer.duplicate());
}
size += buffer.remaining();
return this;
}
public InputStream wrap(InputStream stream) {
return new FilterInputStream(stream) {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment