У жёсткого диска (HDD) есть подвижная головка, которая стоит над каким-то
цилиндром. Чтобы прочитать данные с другого цилиндра, головку нужно физически
передвинуть — а это самая медленная операция. Чем меньше суммарный путь головки,
тем быстрее обслужены все запросы.
Реализуй функцию, которая считает суммарное перемещение головки (в цилиндрах)
для очереди запросов при заданной политике планирования:
func TotalSeek(start int, requests []int, policy string) int
start — начальный цилиндр, над которым стоит головка;
requests — номера цилиндров, которые нужно обслужить;
policy — одна из трёх стратегий: "FIFO", "SSTF", "SCAN".
Стратегии:
- FIFO — обслуживаем строго в порядке прихода. Сумма модулей всех переходов.
- SSTF (Shortest Seek Time First) — каждый раз идём к ближайшему к текущей
позиции запросу. Если два запроса на одинаковом расстоянии — берём тот, у
которого меньше номер цилиндра.
- SCAN («лифт») — сначала движемся в сторону бо́льших цилиндров, обслуживая
все запросы по пути, доходим до самого большого запроса и разворачиваемся к
меньшим, обслуживая оставшиеся. До физического края диска не доезжаем — только до
крайнего запроса.
Возвращаем суммарную пройденную дистанцию.
Один и тот же набор для трёх политик (классический пример), start = 53,
requests = [98, 183, 37, 122, 14, 124, 65, 67]:
TotalSeek(53, []int{98, 183, 37, 122, 14, 124, 65, 67}, "FIFO") // → 640
TotalSeek(53, []int{98, 183, 37, 122, 14, 124, 65, 67}, "SSTF") // → 236
TotalSeek(53, []int{98, 183, 37, 122, 14, 124, 65, 67}, "SCAN") // → 299
Видно, как SSTF и SCAN экономят путь по сравнению с наивным FIFO.
Краевые случаи:
TotalSeek(50, nil, "FIFO") // → 0 (нет запросов)
TotalSeek(50, []int{30}, "SSTF") // → 20 (один запрос: |50-30|)
Подробнее про устройство диска — в главе «Жёсткий диск».