Skip to content

Add disk scheduling algorithms. #5748

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 23 commits into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.thealgorithms.scheduling.diskscheduling;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Circular Look Scheduling (C-LOOK) is a disk scheduling algorithm similar to
* the C-SCAN algorithm but with a key difference. In C-LOOK, the disk arm also
* moves in one direction to service requests, but instead of going all the way
* to the end of the disk, it only goes as far as the furthest request in the
* current direction. After servicing the last request in the current direction,
* the arm immediately jumps back to the closest request on the other side without
* moving to the disk's extreme ends. This reduces the unnecessary movement of the
* disk arm, resulting in better performance compared to C-SCAN, while still
* maintaining fair wait times for requests.
*/
public class CircularLookScheduling {
private int currentPosition;
private boolean movingUp;
private final int maxCylinder;

public CircularLookScheduling(int startPosition, boolean movingUp, int maxCylinder) {
this.currentPosition = startPosition;
this.movingUp = movingUp;
this.maxCylinder = maxCylinder;
}

public List<Integer> execute(List<Integer> requests) {
List<Integer> result = new ArrayList<>();

// Filter and sort valid requests in both directions
List<Integer> upRequests = new ArrayList<>();
List<Integer> downRequests = new ArrayList<>();

for (int request : requests) {
if (request >= 0 && request < maxCylinder) {
if (request > currentPosition) {
upRequests.add(request);
} else if (request < currentPosition) {
downRequests.add(request);
}
}
}

Collections.sort(upRequests);
Collections.sort(downRequests);

if (movingUp) {
// Process all requests in the upward direction
result.addAll(upRequests);

// Jump to the lowest request and process all requests in the downward direction
result.addAll(downRequests);
} else {
// Process all requests in the downward direction (in reverse order)
Collections.reverse(downRequests);
result.addAll(downRequests);

// Jump to the highest request and process all requests in the upward direction (in reverse order)
Collections.reverse(upRequests);
result.addAll(upRequests);
}

// Update current position to the last processed request
if (!result.isEmpty()) {
currentPosition = result.get(result.size() - 1);
}

return result;
}

public int getCurrentPosition() {
return currentPosition;
}

public boolean isMovingUp() {
return movingUp;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package com.thealgorithms.scheduling.diskscheduling;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* Circular Scan Scheduling (C-SCAN) is a disk scheduling algorithm that
* works by moving the disk arm in one direction to service requests until
* it reaches the end of the disk. Once it reaches the end, instead of reversing
* direction like in the SCAN algorithm, the arm moves back to the starting point
* without servicing any requests. This ensures a more uniform wait time for all
* requests, especially those near the disk edges. The algorithm then continues in
* the same direction, making it effective for balancing service time across all disk sectors.
*/
public class CircularScanScheduling {
private int currentPosition;
private boolean movingUp;
private final int diskSize;

public CircularScanScheduling(int startPosition, boolean movingUp, int diskSize) {
this.currentPosition = startPosition;
this.movingUp = movingUp;
this.diskSize = diskSize;
}

public List<Integer> execute(List<Integer> requests) {
if (requests.isEmpty()) {
return new ArrayList<>(); // Return empty list if there are no requests
}

List<Integer> sortedRequests = new ArrayList<>(requests);
Collections.sort(sortedRequests);

List<Integer> result = new ArrayList<>();

if (movingUp) {
// Moving up: process requests >= current position
for (int request : sortedRequests) {
if (request >= currentPosition && request < diskSize) {
result.add(request);
}
}

// Jump to the smallest request and continue processing from the start
for (int request : sortedRequests) {
if (request < currentPosition) {
result.add(request);
}
}
} else {
// Moving down: process requests <= current position in reverse order
for (int i = sortedRequests.size() - 1; i >= 0; i--) {
int request = sortedRequests.get(i);
if (request <= currentPosition) {
result.add(request);
}
}

// Jump to the largest request and continue processing in reverse order
for (int i = sortedRequests.size() - 1; i >= 0; i--) {
int request = sortedRequests.get(i);
if (request > currentPosition) {
result.add(request);
}
}
}

// Set final position to the last request processed
if (!result.isEmpty()) {
currentPosition = result.get(result.size() - 1);
}
return result;
}

public int getCurrentPosition() {
return currentPosition;
}

public boolean isMovingUp() {
return movingUp;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
package com.thealgorithms.scheduling.diskscheduling;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
* https://en.wikipedia.org/wiki/LOOK_algorithm
* Look Scheduling algorithm implementation.
* The Look algorithm moves the disk arm to the closest request in the current direction,
* and once it processes all requests in that direction, it reverses the direction.
*/
public class LookScheduling {
private final int maxTrack;
private final int currentPosition;
private boolean movingUp;
private int farthestPosition;
public LookScheduling(int startPosition, boolean initialDirection, int maxTrack) {
this.currentPosition = startPosition;
this.movingUp = initialDirection;
this.maxTrack = maxTrack;
}

/**
* Executes the Look Scheduling algorithm on the given list of requests.
*
* @param requests List of disk requests.
* @return Order in which requests are processed.
*/
public List<Integer> execute(List<Integer> requests) {
List<Integer> result = new ArrayList<>();
List<Integer> lower = new ArrayList<>();
List<Integer> upper = new ArrayList<>();

// Split requests into two lists based on their position relative to current position
for (int request : requests) {
if (request >= 0 && request < maxTrack) {
if (request < currentPosition) {
lower.add(request);
} else {
upper.add(request);
}
}
}

// Sort the requests
Collections.sort(lower);
Collections.sort(upper);

// Process the requests depending on the initial moving direction
if (movingUp) {
// Process requests in the upward direction
result.addAll(upper);
if (!upper.isEmpty()) {
farthestPosition = upper.get(upper.size() - 1);
}

// Reverse the direction and process downward
movingUp = false;
Collections.reverse(lower);
result.addAll(lower);
if (!lower.isEmpty()) {
farthestPosition = Math.max(farthestPosition, lower.get(0));
}
} else {
// Process requests in the downward direction
Collections.reverse(lower);
result.addAll(lower);
if (!lower.isEmpty()) {
farthestPosition = lower.get(0);
}

// Reverse the direction and process upward
movingUp = true;
result.addAll(upper);
if (!upper.isEmpty()) {
farthestPosition = Math.max(farthestPosition, upper.get(upper.size() - 1));
}
}

return result;
}

public int getCurrentPosition() {
return currentPosition;
}

public boolean isMovingUp() {
return movingUp;
}

public int getFarthestPosition() {
return farthestPosition;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.thealgorithms.scheduling.diskscheduling;

import java.util.ArrayList;
import java.util.List;

/**
*https://en.wikipedia.org/wiki/Shortest_seek_first
* Shortest Seek First (SFF) Scheduling algorithm implementation.
* The SFF algorithm selects the next request to be serviced based on the shortest distance
* from the current position of the disk arm. It continuously evaluates all pending requests
* and chooses the one that requires the least amount of movement to service.
*
* This approach minimizes the average seek time, making it efficient in terms of response
* time for individual requests. However, it may lead to starvation for requests located
* further away from the current position of the disk arm.
*
* The SFF algorithm is particularly effective in systems where quick response time
* is crucial, as it ensures that the most accessible requests are prioritized for servicing.
*/
public class SSFScheduling {
private int currentPosition;

public SSFScheduling(int currentPosition) {
this.currentPosition = currentPosition;
}

public List<Integer> execute(List<Integer> requests) {
List<Integer> result = new ArrayList<>(requests);
List<Integer> orderedRequests = new ArrayList<>();

while (!result.isEmpty()) {
int closest = findClosest(result);
orderedRequests.add(closest);
result.remove(Integer.valueOf(closest));
currentPosition = closest;
}
return orderedRequests;
}

private int findClosest(List<Integer> requests) {
int minDistance = Integer.MAX_VALUE;
int closest = -1;
for (int request : requests) {
int distance = Math.abs(currentPosition - request);
if (distance < minDistance) {
minDistance = distance;
closest = request;
}
}
return closest;
}

public int getCurrentPosition() {
return currentPosition;
}
}
Loading