Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/main/java/org/apache/maven/buildcache/hash/Hash.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,12 @@ public interface Factory {

Checksum checksum(int count);
}

/**
* Memory policy
*/
public enum MemoryPolicy {
Standard,
MemoryMappedBuffers
}
}
20 changes: 12 additions & 8 deletions src/main/java/org/apache/maven/buildcache/hash/HashFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,18 @@
* HashFactory
*/
public enum HashFactory {
SHA1(new SHA("SHA-1")),
SHA256(new SHA("SHA-256")),
SHA384(new SHA("SHA-384")),
SHA512(new SHA("SHA-512")),
XX(new Zah("XX", LongHashFunction.xx(), Zah.MemoryPolicy.Standard)),
XXMM(new Zah("XXMM", LongHashFunction.xx(), Zah.MemoryPolicy.MemoryMappedBuffers)),
METRO(new Zah("METRO", LongHashFunction.metro(), Zah.MemoryPolicy.Standard)),
METRO_MM(new Zah("METRO+MM", LongHashFunction.metro(), Zah.MemoryPolicy.MemoryMappedBuffers));
SHA1(new SHA("SHA-1", Hash.MemoryPolicy.Standard)),
SHA1_MM(new SHA("SHA-1", Hash.MemoryPolicy.MemoryMappedBuffers)),
SHA256(new SHA("SHA-256", Hash.MemoryPolicy.Standard)),
SHA256_MM(new SHA("SHA-256", Hash.MemoryPolicy.MemoryMappedBuffers)),
SHA384(new SHA("SHA-384", Hash.MemoryPolicy.Standard)),
SHA384_MM(new SHA("SHA-384", Hash.MemoryPolicy.MemoryMappedBuffers)),
SHA512(new SHA("SHA-512", Hash.MemoryPolicy.Standard)),
SHA512_MM(new SHA("SHA-512", Hash.MemoryPolicy.MemoryMappedBuffers)),
XX(new Zah("XX", LongHashFunction.xx(), Hash.MemoryPolicy.Standard)),
XXMM(new Zah("XXMM", LongHashFunction.xx(), Hash.MemoryPolicy.MemoryMappedBuffers)),
METRO(new Zah("METRO", LongHashFunction.metro(), Hash.MemoryPolicy.Standard)),
METRO_MM(new Zah("METRO+MM", LongHashFunction.metro(), Hash.MemoryPolicy.MemoryMappedBuffers));

private static final Map<String, HashFactory> LOOKUP = new HashMap<>();

Expand Down
37 changes: 35 additions & 2 deletions src/main/java/org/apache/maven/buildcache/hash/SHA.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,14 @@
package org.apache.maven.buildcache.hash;

import java.io.IOException;
import java.nio.channels.FileChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.MessageDigest;

import static java.nio.channels.FileChannel.MapMode.READ_ONLY;
import static java.nio.file.StandardOpenOption.READ;

/**
* SHA
*/
Expand All @@ -32,9 +36,11 @@ public class SHA implements Hash.Factory {
private static final ThreadLocal<MessageDigest> CHECKSUM = new ThreadLocal<>();

private final String algorithm;
private final Hash.MemoryPolicy memoryPolicy;

SHA(String algorithm) {
SHA(String algorithm, Hash.MemoryPolicy memoryPolicy) {
this.algorithm = algorithm;
this.memoryPolicy = memoryPolicy != null ? memoryPolicy : Hash.MemoryPolicy.Standard;
}

@Override
Expand All @@ -44,7 +50,12 @@ public String getAlgorithm() {

@Override
public Hash.Algorithm algorithm() {
return new SHA.Algorithm(ThreadLocalDigest.get(ALGORITHM, algorithm));
switch (memoryPolicy) {
case MemoryMappedBuffers:
return new AlgorithmWithMM(ThreadLocalDigest.get(ALGORITHM, algorithm));
default:
return new SHA.Algorithm(ThreadLocalDigest.get(ALGORITHM, algorithm));
}
}

@Override
Expand All @@ -71,6 +82,28 @@ public byte[] hash(Path path) throws IOException {
}
}

private static class AlgorithmWithMM implements Hash.Algorithm {
private final MessageDigest digest;

private AlgorithmWithMM(MessageDigest digest) {
this.digest = digest;
}

@Override
public byte[] hash(byte[] array) {
return digest.digest(array);
}

@Override
public byte[] hash(Path path) throws IOException {
try (FileChannel channel = FileChannel.open(path, READ);
CloseableBuffer buffer = CloseableBuffer.mappedBuffer(channel, READ_ONLY)) {
digest.update(buffer.getBuffer());
return digest.digest();
}
}
}

private static class Checksum implements Hash.Checksum {

private final MessageDigest digest;
Expand Down
11 changes: 3 additions & 8 deletions src/main/java/org/apache/maven/buildcache/hash/Zah.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,14 @@
*/
public class Zah implements Hash.Factory {

public enum MemoryPolicy {
Standard,
MemoryMappedBuffers
}

private final String name;
private final LongHashFunction hash;
private final MemoryPolicy memoryPolicy;
private final Hash.MemoryPolicy memoryPolicy;

public Zah(String name, LongHashFunction hash, MemoryPolicy memoryPolicy) {
public Zah(String name, LongHashFunction hash, Hash.MemoryPolicy memoryPolicy) {
this.name = name;
this.hash = hash;
this.memoryPolicy = memoryPolicy != null ? memoryPolicy : MemoryPolicy.Standard;
this.memoryPolicy = memoryPolicy != null ? memoryPolicy : Hash.MemoryPolicy.Standard;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,16 @@
* specific language governing permissions and limitations
* under the License.
*/
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;

import org.apache.maven.buildcache.hash.HashAlgorithm;
import org.apache.maven.buildcache.hash.HashChecksum;
import org.apache.maven.buildcache.hash.HashFactory;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import static org.apache.maven.buildcache.hash.HashFactory.SHA256;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -57,22 +62,35 @@ class SHAHashTest {
private static final String FULL_CHECKSUM = "7305db9b2abccd706c256db3d97e5ff48d677cfe4d3a5904afb7da0e3950e1e2";

private static final HashAlgorithm ALGORITHM = SHA256.createAlgorithm();
private static final HashAlgorithm ALGORITHM_MM = HashFactory.SHA256_MM.createAlgorithm();

private static final HashChecksum CHECKSUM = SHA256.createChecksum(0);

@TempDir
Path tempDir;

@Test
void testEmptyArray() {
byte[] emptyArray = new byte[0];
String hash = ALGORITHM.hash(emptyArray);
assertEquals(EMPTY_HASH, hash);
assertEquals(EMPTY_HASH, ALGORITHM.hash(emptyArray));
}

@Test
void testSimpleHash() {
String helloHash = ALGORITHM.hash(HELLO_ARRAY);
assertEquals(HELLO_HASH, helloHash);

String worldHash = ALGORITHM.hash(WORLD_ARRAY);
assertEquals(WORLD_HASH, worldHash);
assertEquals(WORLD_HASH, ALGORITHM.hash(WORLD_ARRAY));
assertEquals(WORLD_HASH, ALGORITHM_MM.hash(WORLD_ARRAY));
}

@Test
void testFileHash() throws IOException {
Path testFile = tempDir.resolve("SHAHashTest.txt");
Files.write(testFile, HELLO_ARRAY);

assertEquals(HELLO_HASH, ALGORITHM.hash(testFile));
assertEquals(HELLO_HASH, ALGORITHM_MM.hash(testFile));
}

@Test
Expand Down
5 changes: 5 additions & 0 deletions src/test/java/org/apache/maven/buildcache/hash/PerfTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ public String sha256(HashState state) throws IOException {
return doTest(HashFactory.SHA256, state);
}

@Benchmark
public String sha256mm(HashState state) throws IOException {
return doTest(HashFactory.SHA256_MM, state);
}

@Benchmark
public String xx(HashState state) throws IOException {
return doTest(HashFactory.XX, state);
Expand Down