Skip to content

Instantly share code, notes, and snippets.

@joshlemer
Created February 28, 2019 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save joshlemer/ac8cef75047c7bb699b7d75e8d4178d0 to your computer and use it in GitHub Desktop.
Save joshlemer/ac8cef75047c7bb699b7d75e8d4178d0 to your computer and use it in GitHub Desktop.
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