操作系统课程设计 —— 磁盘调度算法

talk is easy, show the code

import java.util.*
import kotlin.math.abs

/**
 * 磁盘调度算法工厂类, 构造器私有化, 防止外部类实例化
 */
class DiskScheduleFactory private constructor() {

    /**
     * 磁盘调度算法接口, 不对外开放
     */
    private interface DiskScheduling {
        /**
         * 磁头移动路径数据
         * @property moveCount Int
         * @property allDistance Int
         * @property lastPosition Int
         * @constructor
         */
        data class Data(val moveCount: Int, val allDistance: Int, val lastPosition: Int) {
            /**
             * 重载 + 号, 方便合并两部分数据
             * @param other Data
             * @return Data
             */
            operator fun plus(other: Data) = Data(
                other.moveCount + moveCount,
                other.allDistance + allDistance,
                lastPosition
            )

            /**
             * 将数据以人类能看的方式显示出来
             * @return String
             */
            override fun toString(): String {
                return "moveCount -> $moveCount allDistance = $allDistance"
            }
        }

        /**
         * 具体算法实现方法
         * @param visitList IntArray
         * @param currentPosition Int
         * @param upList LinkedList<Int>
         * @param downList LinkedList<Int>
         */
        fun doStuff(visitList: IntArray, currentPosition: Int, upList: LinkedList<Int>, downList: LinkedList<Int>)

        /**
         * 遍历列表辅助方法
         * @param visitList IntArray
         * @param currentPosition Int
         * @return Data
         */
        fun forEach(visitList: IntArray, currentPosition: Int): Data {
            var head = currentPosition
            var currentDistance: Int
            var allDistance = 0
            var moveCount = 0
            visitList.forEach {
                currentDistance = abs(head - it)
                println("磁头移动 $head -> $it, 移动距离为 $currentDistance")
                head = it
                allDistance += currentDistance
                moveCount += 1
            }
            return Data(moveCount, allDistance, visitList.last())
        }

        /**
         * 输出数据
         * @param data Data
         */
        fun outData(data: Data) {
            println("总共移动了 ${data.moveCount} 下, 移动距离为 ${data.allDistance} 平均移动距离为 ${data.allDistance / data.moveCount}")
        }
    }

    /**
     * 算法实现枚举类, 不对外开放
     */
    private enum class DiskScheduleImpl : DiskScheduling {
        /**
         * 先来先服务算法
         */
        FCFS {
            override fun doStuff(
                visitList: IntArray,
                currentPosition: Int,
                upList: LinkedList<Int>,
                downList: LinkedList<Int>
            ) {
                outData(forEach(visitList, currentPosition))
            }
        },

        /**
         * 最短寻道时间算法
         */
        SSTF {
            override fun doStuff(
                visitList: IntArray,
                currentPosition: Int,
                upList: LinkedList<Int>,
                downList: LinkedList<Int>
            ) {
                val allData = forEach(visitList.sortedWith(compareBy {
                    abs(it - currentPosition)
                }).toIntArray(), currentPosition)
                outData(allData)
            }
        },

        /**
         * 电梯算法 自下往上
         */
        SCAN_UP {
            override fun doStuff(
                visitList: IntArray,
                currentPosition: Int,
                upList: LinkedList<Int>,
                downList: LinkedList<Int>
            ) {
                // 从大到小排序
                downList.reverse()
                // 先往上走
                val upData = forEach(upList.toIntArray(), currentPosition)
                // 再往上走
                val downData = forEach(downList.toIntArray(), upData.lastPosition)
                // 算出总共的
                val allData = downData + upData
                outData(allData)
            }
        },

        /**
         * 电梯算法 自上往下
         */
        SCAN_DOWN {
            override fun doStuff(
                visitList: IntArray,
                currentPosition: Int,
                upList: LinkedList<Int>,
                downList: LinkedList<Int>
            ) {
                // 从大到小排序
                downList.reverse()
                // 先往下走
                val downData = forEach(downList.toIntArray(), currentPosition)
                // 再往上走
                val upData = forEach(upList.toIntArray(), downData.lastPosition)
                // 算出总共的
                val allData = downData + upData
                outData(allData)
            }
        },

        /**
         * 单项扫描算法
         */
        C_SCAN {
            override fun doStuff(
                visitList: IntArray,
                currentPosition: Int,
                upList: LinkedList<Int>,
                downList: LinkedList<Int>
            ) {
                // 走到头后归零
                downList.push(0)
                // 先往上走
                val upData = forEach(upList.toIntArray(), currentPosition)
                // 再往上走
                val downData = forEach(downList.toIntArray(), upData.lastPosition)
                // 算出总共的
                val allData = downData + upData
                outData(allData)
            }
        }
    }

    /**
     * 伴生对象, 创建实例的方法
     */
    companion object {
        private lateinit var instance: DiskScheduleImpl

        /**
         * 根据算法名获取相应的算法对象
         * @param algorithm String
         * @return DiskScheduleFactory
         */
        fun getInstance(algorithm: String): DiskScheduleFactory {
            runCatching {
                instance = DiskScheduleImpl.valueOf(algorithm)
            }.onFailure {
                throw IllegalArgumentException("算法不支持!")
            }
            return DiskScheduleFactory()
        }
    }

    /**
     * 代理调用算法
     * @param visitList IntArray
     * @param currentPosition Int
     */
    fun doStuff(visitList: IntArray, currentPosition: Int) {
        val downList = LinkedList<Int>()
        val upList = LinkedList<Int>()
        // 除了先来先服务算法, 其他都需要升序排序
        if (instance != DiskScheduleImpl.FCFS)
            visitList.sort()
        // 电梯算法和单向扫描算法需要分离上下层
        if (
            instance == DiskScheduleImpl.SCAN_DOWN ||
            instance == DiskScheduleImpl.SCAN_UP ||
            instance == DiskScheduleImpl.C_SCAN
        ) {
            // 分离 上层 与 下层
            visitList.forEach {
                if (it <= currentPosition)
                    downList.add(it)
                else
                    upList.add(it)
            }
        }
        instance.doStuff(visitList, currentPosition, upList, downList)
    }

object Main {

    @JvmStatic
    fun main(args: Array<String>) {
        // 一共 8 条记录
        val visitDisk = intArrayOf(98, 183, 37, 122, 14, 124, 65, 67)
        DiskScheduleFactory.getInstance("SCAN_DOWN")
            .doStuff(visitDisk, 53)
    }
}
posted @ 2021-08-30 08:18  博麗靈夢  阅读(209)  评论(0编辑  收藏  举报