From: Svjatoslav Agejenko Date: Sun, 28 Dec 2025 18:27:19 +0000 (+0200) Subject: Refactor `TaskProcessorCommand` to use `TaskPriorityQueue` for improved task prioriti... X-Git-Url: http://www2.svjatoslav.eu/gitweb/?a=commitdiff_plain;h=3229bebcffea81816aad1e1c906ade7d6189d6b2;p=alyverkko-cli.git Refactor `TaskProcessorCommand` to use `TaskPriorityQueue` for improved task prioritization and management. --- diff --git a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskPriorityQueue.java b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskPriorityQueue.java new file mode 100644 index 0000000..23d12df --- /dev/null +++ b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskPriorityQueue.java @@ -0,0 +1,62 @@ +package eu.svjatoslav.alyverkko_cli.commands.task_processor; + +import java.util.*; +import java.util.function.Predicate; +import eu.svjatoslav.alyverkko_cli.commands.task_processor.TaskProcessorCommand.TaskQueueEntry; + + +/** + * A custom priority queue implementation for TaskQueueEntry that maintains tasks in priority order. + * Uses a TreeSet for efficient insertion, polling, and iteration. + */ +public class TaskPriorityQueue { + private final TreeSet tasks; + + /** + * Constructs a new empty task priority queue. + */ + public TaskPriorityQueue() { + tasks = new TreeSet<>(); + } + + /** + * Adds a task to the priority queue. + * + * @param task the task to add (must not be null) + */ + public void add(TaskQueueEntry task) { + tasks.add(task); + } + + /** + * Removes and returns the highest priority task from the queue. + * + * @return the highest priority task, or null if the queue is empty + */ + public TaskQueueEntry poll() { + if (tasks.isEmpty()) { + return null; + } + TaskQueueEntry task = tasks.first(); + tasks.remove(task); + return task; + } + + /** + * Removes tasks matching the given predicate. + * + * @param predicate the condition for removal (must not be null) + */ + public void removeIf(Predicate predicate) { + tasks.removeIf(predicate); + } + + /** + * Returns all tasks in the queue in order of priority (highest priority first). + * + * @return a new list containing all tasks in priority order + */ + public List getAllTasks() { + return new ArrayList<>(tasks); + } +} diff --git a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskProcessorCommand.java b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskProcessorCommand.java index 07b96f4..596cb98 100644 --- a/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskProcessorCommand.java +++ b/src/main/java/eu/svjatoslav/alyverkko_cli/commands/task_processor/TaskProcessorCommand.java @@ -37,6 +37,11 @@ import static java.nio.file.StandardWatchEventKinds.*; */ public class TaskProcessorCommand implements Command { + /** + * A custom priority queue implementation that maintains tasks in priority order. + */ + private final TaskPriorityQueue taskQueue = new TaskPriorityQueue(); + /** * A command-line parser to handle "mail" command arguments. */ @@ -65,12 +70,6 @@ public class TaskProcessorCommand implements Command { */ File taskDirectory; - /** - * Priority queue of tasks to process, sorted by priority and a - * random tiebreaker. - */ - private final PriorityQueue taskQueue; - public TaskProcessorCommand() { Comparator comparator = (a, b) -> { int priorityCompare = Integer.compare(b.priority, a.priority); @@ -79,7 +78,6 @@ public class TaskProcessorCommand implements Command { } return a.tiebreaker.compareTo(b.tiebreaker); }; - this.taskQueue = new PriorityQueue<>(comparator); } /** @@ -127,7 +125,8 @@ public class TaskProcessorCommand implements Command { // Main loop: process tasks from the queue in priority order while (true) { // Process the highest priority task if available - if (!taskQueue.isEmpty()) processTask(taskQueue.poll()); + TaskQueueEntry nextTask = taskQueue.poll(); + if (nextTask != null) processTask(nextTask); // Check for filesystem events WatchKey key = directoryWatcher.poll(); @@ -484,14 +483,14 @@ public class TaskProcessorCommand implements Command { System.err.println("Invalid priority in file " + filePath.getFileName() + ": " + priorityStr); } } - taskQueue.offer(new TaskQueueEntry(filePath, priority)); + taskQueue.add(new TaskQueueEntry(filePath, priority)); } /** * A static nested class representing a task in the queue, with a * priority and a tiebreaker for sorting. */ - private static class TaskQueueEntry implements Comparable { + public static class TaskQueueEntry implements Comparable { private final Path filePath; private final int priority; private final String tiebreaker; @@ -526,26 +525,11 @@ public class TaskProcessorCommand implements Command { /** * Removes all tasks from the queue that match the given file path. - * This is done by draining the queue into a list, filtering out the matching entries, - * and re-adding the remaining ones back into the queue. * * @param filePath the file path to match and remove from the queue. */ private void removeTasksForFile(Path filePath) { - List remaining = new ArrayList<>(); - - // Drain all elements into a list - while (!taskQueue.isEmpty()) { - TaskQueueEntry entry = taskQueue.poll(); - if (!entry.getFilePath().equals(filePath)) { - remaining.add(entry); - } - } - - // Re-add all remaining entries back to the queue - for (TaskQueueEntry entry : remaining) { - taskQueue.offer(entry); - } + taskQueue.removeIf(entry -> entry.getFilePath().equals(filePath)); } }