Skip to content

Instantly share code, notes, and snippets.

@alancnet
Created September 28, 2016 23:42
Show Gist options
  • Save alancnet/942e66e5d7357bfd5aed23f404e36294 to your computer and use it in GitHub Desktop.
Save alancnet/942e66e5d7357bfd5aed23f404e36294 to your computer and use it in GitHub Desktop.
A slow, super large heirarchial hash set thing using files.
import java.io.{File, RandomAccessFile}
class RandomAccessFileHashSet(file: File) {
val raf = new RandomAccessFile(file, "rw")
def filePosition = raf.getFilePointer
def fileLength = raf.length
var recordCount: Long = 0L
raf.writeLong(recordCount)
val hashStart = filePosition
def seek(position: Long) = raf.seek(Math.abs(position))
def incrementRecordCount() = {
val originalPos = filePosition
recordCount = recordCount + 1
seek(0)
raf.writeLong(recordCount)
seek(originalPos)
println(s"Count: $recordCount")
}
def add(value: Array[Byte]): Unit = {
val originalPos = filePosition
val isNew = filePosition == fileLength
// Ensure record exists at byte offset
if (isNew) {
0.to(256).foreach((x) => {
raf.writeLong(0L)
})
seek(originalPos)
if (value.isEmpty) {
incrementRecordCount()
}
}
// Read record for next offset
if (value.nonEmpty) {
// Find the next offset
val newPos: Long = value.head.toLong * java.lang.Long.BYTES + filePosition
seek(newPos)
val nextOffset = raf.readLong()
if (nextOffset == 0L) {
// We need to add another record.
seek(newPos)
if (value.tail.isEmpty){
raf.writeLong(-1 * fileLength)
} else {
raf.writeLong(fileLength)
}
seek(fileLength)
} else {
if (value.tail.isEmpty && nextOffset > 0L) {
seek(newPos)
raf.writeLong(-1 * nextOffset)
incrementRecordCount()
}
seek(nextOffset)
}
add(value.tail)
} else {
seek(hashStart)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment