Skip to content

Commit 685bd6f

Browse files
Merge pull request #110 from fa93hws/file-channel
use file channel to improve content hash efficiency
2 parents 455562c + cd3a349 commit 685bd6f

File tree

2 files changed

+39
-17
lines changed

2 files changed

+39
-17
lines changed

src/main/java/com/bazel_diff/BazelClient.java

+2-3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import com.google.devtools.build.lib.query2.proto.proto2api.Build;
44

5-
import com.google.common.collect.Iterables;
6-
75
import java.io.*;
86
import java.nio.charset.StandardCharsets;
97
import java.io.IOException;
@@ -93,7 +91,8 @@ private Map<String, BazelSourceFileTarget> processBazelSourcefileTargets(List<Bu
9391
BazelSourceFileTargetImpl sourceFileTarget = new BazelSourceFileTargetImpl(
9492
sourceFile.getName(),
9593
digest.digest().clone(),
96-
readSourcefileTargets ? workingDirectory : null
94+
readSourcefileTargets ? workingDirectory : null,
95+
verbose
9796
);
9897
sourceTargets.put(sourceFileTarget.getName(), sourceFileTarget);
9998
}

src/main/java/com/bazel_diff/BazelSourceFileTarget.java

+37-14
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package com.bazel_diff;
22

3-
import java.io.ByteArrayOutputStream;
4-
import java.io.File;
5-
import java.io.FileInputStream;
6-
import java.io.IOException;
7-
import java.nio.file.Files;
3+
import java.io.*;
4+
import java.nio.ByteBuffer;
5+
import java.nio.channels.FileChannel;
86
import java.nio.file.Path;
7+
import java.nio.file.Paths;
8+
import java.io.IOException;
99
import java.security.MessageDigest;
1010
import java.security.NoSuchAlgorithmException;
1111

@@ -18,21 +18,44 @@ class BazelSourceFileTargetImpl implements BazelSourceFileTarget {
1818
private String name;
1919
private byte[] digest;
2020

21-
BazelSourceFileTargetImpl(String name, byte[] digest, Path workingDirectory)
21+
private void digestLargeFile(MessageDigest finalDigest, FileChannel inChannel) throws IOException {
22+
int bufferSize = 10240; // 10kb
23+
ByteBuffer buffer = ByteBuffer.allocate(bufferSize);
24+
while (inChannel.read(buffer) != -1) {
25+
buffer.flip();
26+
finalDigest.update(buffer);
27+
buffer.clear();
28+
}
29+
}
30+
31+
private void digestSmallFile(MessageDigest finalDigest, FileChannel inChannel) throws IOException {
32+
long fileSize = inChannel.size();
33+
ByteBuffer buffer = ByteBuffer.allocate((int) fileSize);
34+
inChannel.read(buffer);
35+
buffer.flip();
36+
finalDigest.update(buffer);
37+
}
38+
39+
BazelSourceFileTargetImpl(String name, byte[] digest, Path workingDirectory, Boolean verbose)
2240
throws IOException, NoSuchAlgorithmException {
2341
this.name = name;
2442
MessageDigest finalDigest = MessageDigest.getInstance("SHA-256");
2543
if (workingDirectory != null && name.startsWith("//")) {
2644
String filenameSubstring = name.substring(2);
2745
String filenamePath = filenameSubstring.replaceFirst(":", "/");
28-
File sourceFile = new File(workingDirectory.toString(), filenamePath);
29-
if (sourceFile.isFile() && sourceFile.canRead()) {
30-
byte[] buffer = new byte[16384];
31-
FileInputStream in = new FileInputStream(sourceFile);
32-
int rc = in.read(buffer);
33-
while (rc != -1) {
34-
finalDigest.update(buffer, 0, rc);
35-
rc = in.read(buffer);
46+
Path absoluteFilePath = Paths.get(workingDirectory.toString(), filenamePath);
47+
try (RandomAccessFile sourceFile = new RandomAccessFile(absoluteFilePath.toString(), "r")) {
48+
FileChannel inChannel = sourceFile.getChannel();
49+
if (inChannel.size() > 1048576) { // 1mb
50+
digestLargeFile(finalDigest, inChannel);
51+
} else {
52+
digestSmallFile(finalDigest, inChannel);
53+
}
54+
sourceFile.close();
55+
inChannel.close();
56+
} catch (FileNotFoundException e) {
57+
if (verbose) {
58+
System.out.printf("BazelDiff: [Warning] file %s not found%n", absoluteFilePath);
3659
}
3760
}
3861
}

0 commit comments

Comments
 (0)