Files
disk-scheduling/script.js
T
2024-11-27 10:13:38 +08:00

208 lines
6.5 KiB
JavaScript

let head;
let requests = [];
let currentIndex = 0;
let seekTime = 0;
let direction = 1; // 1 for right, -1 for left
let animationInterval;
function initialize() {
head = document.getElementById("head");
const diskTrack = document.getElementById("diskTrack");
const trackWidth = diskTrack.offsetWidth;
const headWidth = 12;
// Clear existing requests
const existingRequests = document.querySelectorAll(".request");
existingRequests.forEach((req) => req.remove());
// Get initial head position and requests
const initialHead = parseInt(document.getElementById("initialHead").value);
const requestInput = document.getElementById("requestQueue").value;
requests = requestInput.split(",").map((x) => parseInt(x.trim()));
// Set initial head position
const headPosition = (initialHead / 199) * trackWidth;
head.style.left = headPosition + "px";
// Place request points
requests.forEach((pos) => {
const request = document.createElement("div");
request.className = "request";
request.style.left = (pos / 199) * trackWidth + "px";
diskTrack.appendChild(request);
});
// Reset statistics
seekTime = 0;
currentIndex = 0;
direction = 1;
updateStats(initialHead);
}
function updateStats(position) {
document.getElementById("seekTime").textContent = seekTime;
document.getElementById("currentPos").textContent = position;
}
function startFCFS() {
reset();
const diskTrack = document.getElementById("diskTrack");
const trackWidth = diskTrack.offsetWidth;
const headWidth = 12;
const initialHead = parseInt(document.getElementById("initialHead").value);
let currentPosition = initialHead;
let currentRequestIndex = 0;
animationInterval = setInterval(() => {
if (currentRequestIndex >= requests.length) {
clearInterval(animationInterval);
return;
}
const targetPosition = requests[currentRequestIndex];
const targetPixel = (targetPosition / 199) * trackWidth;
seekTime += Math.abs(targetPosition - currentPosition);
currentPosition = targetPosition;
head.style.left = targetPixel + "px";
const requestElements = document.querySelectorAll(".request");
requestElements.forEach((req) => {
const reqPos =
((parseFloat(req.style.left) - headWidth / 2) /
(trackWidth - headWidth)) *
199;
if (Math.abs(reqPos - targetPosition) < 1) {
req.classList.add("served");
}
});
direction = currentPosition > targetPosition ? -1 : 1;
updateStats(targetPosition);
currentRequestIndex++;
}, 1000);
}
function startSSTF() {
reset();
const diskTrack = document.getElementById("diskTrack");
const trackWidth = diskTrack.offsetWidth;
const headWidth = 12;
const initialHead = parseInt(document.getElementById("initialHead").value);
let currentPosition = initialHead;
let remainingRequests = [...requests];
animationInterval = setInterval(() => {
if (remainingRequests.length === 0) {
clearInterval(animationInterval);
return;
}
let closestRequest = remainingRequests.reduce((closest, current) => {
let closestDistance = Math.abs(closest - currentPosition);
let currentDistance = Math.abs(current - currentPosition);
return currentDistance < closestDistance ? current : closest;
});
remainingRequests = remainingRequests.filter(
(req) => req !== closestRequest
);
const targetPixel = (closestRequest / 199) * trackWidth;
seekTime += Math.abs(closestRequest - currentPosition);
currentPosition = closestRequest;
head.style.left = targetPixel + "px";
const requests = document.querySelectorAll(".request");
requests.forEach((req) => {
const reqPos =
((parseFloat(req.style.left) - headWidth / 2) /
(trackWidth - headWidth)) *
199;
if (Math.abs(reqPos - closestRequest) < 1) {
req.classList.add("served");
}
});
direction = currentPosition > closestRequest ? -1 : 1;
updateStats(closestRequest);
}, 1000);
}
function startSCAN() {
reset();
const diskTrack = document.getElementById("diskTrack");
const trackWidth = diskTrack.offsetWidth;
const headWidth = 12;
const initialHead = parseInt(document.getElementById("initialHead").value);
const initialDirection = document.getElementById("scanDirection").value;
let currentPosition = initialHead;
let sortedRequests = [...requests].sort((a, b) => a - b);
let headIndex = sortedRequests.findIndex((x) => x >= initialHead);
if (headIndex === -1) headIndex = sortedRequests.length;
let scanOrder;
if (initialDirection === "right") {
scanOrder = [
...sortedRequests.slice(headIndex),
...sortedRequests.slice(0, headIndex).reverse(),
];
direction = 1;
} else {
scanOrder = [
...sortedRequests.slice(0, headIndex).reverse(),
...sortedRequests.slice(headIndex),
];
direction = -1;
}
let currentRequestIndex = 0;
animationInterval = setInterval(() => {
if (currentRequestIndex >= scanOrder.length) {
clearInterval(animationInterval);
return;
}
const targetPosition = scanOrder[currentRequestIndex];
const targetPixel = (targetPosition / 199) * trackWidth;
seekTime += Math.abs(targetPosition - currentPosition);
currentPosition = targetPosition;
head.style.left = targetPixel + "px";
const requests = document.querySelectorAll(".request");
requests.forEach((req) => {
const reqPos =
((parseFloat(req.style.left) - headWidth / 2) /
(trackWidth - headWidth)) *
199;
if (Math.abs(reqPos - targetPosition) < 1) {
req.classList.add("served");
}
});
updateStats(targetPosition);
currentRequestIndex++;
}, 1000);
}
function reset() {
if (animationInterval) {
clearInterval(animationInterval);
}
initialize();
}
function markRequestAsServed(request) {
request.classList.add("served");
request.style.animation = "pulse 0.3s ease";
}
window.onload = initialize;