Skip to content

Instantly share code, notes, and snippets.

@zallesov
Last active August 12, 2017 05:35
Show Gist options
  • Save zallesov/e1b758e08d0b2d88202706756c88812b to your computer and use it in GitHub Desktop.
Save zallesov/e1b758e08d0b2d88202706756c88812b to your computer and use it in GitHub Desktop.
import java.io._
import Main.file
import scala.collection.mutable
import scala.util.Random
object Main extends App {
val randomFileName = "random.txt"
val sizeOfInt = 4
val maxChunkSize = 10
class IntItter(file: RandomAccessFile, itemsOffset: Int, itemsNum: Int) extends Iterable[Int] {
file.seek(itemsOffset * sizeOfInt)
override def iterator: Iterator[Int] = new Iterator[Int]() {
override def hasNext: Boolean = {
file.getFilePointer <= (itemsOffset + itemsNum) * sizeOfInt && file.getFilePointer < file.length()
}
override def next(): Int = {
file.readInt()
}
}
}
case class Chunky(chunkNum: Int, position: Int, chunkSize: Int, value:Int) {
def nextOne(file:RandomAccessFile): Chunky = {
val newPosition = position+1
file.seek(chunkNum * chunkSize * sizeOfInt + newPosition * sizeOfInt)
val value = file.readInt
Chunky(chunkNum, newPosition, chunkSize, value)
}
}
def createRandomFile(file: RandomAccessFile, size: Int): Unit = {
file.setLength(size * sizeOfInt)
val random = new Random(123)
(0 to size) foreach { _ =>
file.writeInt(random.nextInt())
}
}
def printFile(file: RandomAccessFile): Unit = {
new IntItter(file, 0, Int.MaxValue).foreach(println(_))
}
def partialySortFile(file: RandomAccessFile, chunksTotal: Int): Unit = {
file.seek(0)
(0 to chunksTotal - 1).foreach { chunkNum =>
val currentChunkSize = math.min(maxChunkSize, (file.length() - chunkNum * maxChunkSize * sizeOfInt) / sizeOfInt).toInt
val chunkOffset = chunkNum * currentChunkSize
val chunkItter = new IntItter(file, chunkOffset, currentChunkSize)
val chunk: Seq[Int] = chunkItter.toSeq.sorted
file.seek(chunkOffset * sizeOfInt)
chunk.foreach(file.writeInt(_))
}
}
def readMinimum(file: RandomAccessFile, chunksTotal: Int): Unit = {
val chunkPositions:mutable.PriorityQueue[Chunky] =
new mutable.PriorityQueue[Chunky]()(Ordering.by[Chunky, Int](_.value)(Ordering[Int].reverse))
(0 to chunksTotal - 1).foreach { chunkNum =>
val currentChunkSize = math.min(maxChunkSize, (file.length() - chunkNum * maxChunkSize * sizeOfInt) / sizeOfInt).toInt
file.seek(chunkNum * currentChunkSize * sizeOfInt)
chunkPositions += Chunky(chunkNum, 0, currentChunkSize, file.readInt())
}
while (chunkPositions.length > 0) {
val chunky: Chunky = chunkPositions.dequeue()
println(chunky.value)
if(chunky.position+1<chunky.chunkSize) {
chunkPositions += chunky.nextOne(file)
}
}
}
val file = new RandomAccessFile(new File(randomFileName), "rw")
createRandomFile(file, 155)
val lengthInInt = ((file.length() - 1) / sizeOfInt).toInt;
val chunksTotal: Int = math.ceil(lengthInInt.toFloat / maxChunkSize.toFloat).toInt;
partialySortFile(file, chunksTotal)
readMinimum(file, chunksTotal)
file.close()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment