Skip to content

Instantly share code, notes, and snippets.

@eed3si9n
Last active August 1, 2023 09:32
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 eed3si9n/e9b253af15938c0387a5ed74c790fda8 to your computer and use it in GitHub Desktop.
Save eed3si9n/e9b253af15938c0387a5ed74c790fda8 to your computer and use it in GitHub Desktop.
package sbt.util
import java.io.File
import java.nio.file.Path
import sjsonnew.{ Builder, JsonWriter }
import StringLongs.StringLong
trait PathHashWriters:
given stringLongLike[A](using conv: Conversion[A, StringLong]): HashWriter[A] with
def write[J](obj: A, builder: Builder[J]): Unit =
val ev = summon[HashWriter[StringLong]]
ev.write(conv(obj), builder)
end PathHashWriters
object PathHashWriters extends PathHashWriters
// Use opaque type to define HashWriter instance
object StringLongs:
opaque type StringLong = (String, Long)
object StringLong:
def apply(first: String, second: Long): StringLong = (first, second)
given Conversion[HashedVirtualFileRef, StringLong] =
(x: HashedVirtualFileRef) => StringLong(x.id, x.contentHash)
given Conversion[File, StringLong] =
(x: File) => StringLong(x.toString(), Hasher.farmHash(x.toPath()))
given Conversion[Path, StringLong] =
(x: Path) => StringLong(x.toString(), Hasher.farmHash(x))
given HashWriter[StringLong] = new HashWriter[StringLong]:
def write[J](obj: StringLong, builder: Builder[J]): Unit =
builder.beginObject()
builder.addFieldName("first")
builder.writeString(obj._1)
builder.addFieldName("second")
builder.writeLong(obj._2)
builder.endObject()
end StringLongs
package sbt.util
import java.io.File
import verify.BasicTestSuite
object HasherTest extends BasicTestSuite:
lazy val hashProtocol = new ImplicitHashWriters() {}
import hashProtocol.*
test("The IntJsonFormat should convert an Int to an int hash") {
import sjsonnew.BasicJsonProtocol.given
val actual = Hasher.hashUnsafe[Int](1)
assert(actual == 1527037976)
}
test("StringLong hashing from the implicit scope") {
import StringLongs.StringLong
val x = StringLongs.StringLong("a.txt", 1)
val actual = Hasher.hashUnsafe(x)
assert(actual == -646160054)
}
test("HashedVirtualFileRef") {
import PathHashWriters.given
val x = HashedVirtualFileRef("a.txt", 1)
val actual = Hasher.hashUnsafe(x)
assert(actual == -646160054)
}
test("java.io.File hash using farmhash") {
import PathHashWriters.given
val x = File("LICENSE")
val actual = Hasher.hashUnsafe(x)
assert(actual == 1218007292)
}
end HasherTest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment