Created
February 28, 2019 18:33
-
-
Save joshlemer/ac8cef75047c7bb699b7d75e8d4178d0 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
calculateFast(file: File, size: Int, hashes: Iterator[ByteString], bitfield: BitVector) = { | |
// zipping iterators together will mean that each element will allocate an additional instance of `Tuple2[Left, Right]` | |
// you could get by with iterating through `file.bytes.grouped(size)` and `hashes` at the same time, avoiding | |
// tuple allocations | |
val iter = file.bytes.grouped(size).zip(hashes) | |
val digest: MessageDigest = MessageDigest.getInstance("SHA-1") | |
val buf = new Array[Byte](size) | |
var bufIdx = 0 | |
var cur: Byte = 0 | |
var offset = 0 | |
while (iter.nonEmpty) { | |
val (xs, hash) = iter.next() | |
// you could use a single buffer array outside of the while loop, which you reuse on each invocation of | |
// digest.update | |
// something like `digest.update(xs.copyToArray(myBuffer)) | |
// maybe this won't work for the last `xs` if it doesn't have an even multiple of `size` bytes, | |
// but you could special case that one maybe | |
digest.update(xs.toArray) | |
// is there a mutable ByteString implementation you can resuse for each iteration of the while loop? | |
val bs = ByteString(digest.digest()) | |
if (offset != 0 && offset % 8 == 0) { | |
buf(bufIdx) = cur | |
cur = 0 | |
bufIdx += 1 | |
} | |
if (bs == hash) | |
cur = (cur | (1 << (7 - offset % 8))).toByte | |
offset += 1 | |
} | |
BitVector.view(buf) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment