Last active
August 12, 2017 05:35
-
-
Save zallesov/e1b758e08d0b2d88202706756c88812b 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
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