Skip to content
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@
* [PreemptivePriorityScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/PreemptivePriorityScheduling.java)
* [RRScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/RRScheduling.java)
* [SJFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SJFScheduling.java)
* [SpeculativeExecutionScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SpeculativeExecutionScheduling.java)
* [SRTFScheduling](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/scheduling/SRTFScheduling.java)
* searches
* [BinarySearch](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/searches/BinarySearch.java)
Expand Down Expand Up @@ -1072,6 +1073,7 @@
* [PreemptivePrioritySchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/PreemptivePrioritySchedulingTest.java)
* [RRSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/RRSchedulingTest.java)
* [SJFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SJFSchedulingTest.java)
* [SpeculativeExecutionSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SpeculativeExecutionSchedulingTest.java)
* [SRTFSchedulingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/scheduling/SRTFSchedulingTest.java)
* searches
* [BinarySearch2dArrayTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/searches/BinarySearch2dArrayTest.java)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.thealgorithms.scheduling;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* SpeculativeExecutionScheduling runs multiple copies of the same task in parallel,
* picking the first one that finishes successfully. It is used to mitigate the
* impact of stragglers (slow tasks).
*
* Use Case: Big data systems like Hadoop and Spark, where it helps improve job completion time.
*
* @author Hardvan
*/
public final class SpeculativeExecutionScheduling {

static class Task {
String name;
boolean completed;

Task(String name) {
this.name = name;
this.completed = false;
}

void complete() {
this.completed = true;
}
}

private final Map<String, List<Task>> taskGroups;

public SpeculativeExecutionScheduling() {
taskGroups = new HashMap<>();
}

/**
* Adds a task to the specified group.
*
* @param groupName the name of the group
* @param taskName the name of the task
*/
public void addTask(String groupName, String taskName) {
List<Task> tasks = taskGroups.computeIfAbsent(groupName, k -> new ArrayList<>());
tasks.add(new Task(taskName));
}

/**
* Executes the tasks in the specified group.
*
* @param groupName the name of the group
* @return the name of the task that completed successfully
*/
public String executeTasks(String groupName) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please provide reference explanation of this algorithm

List<Task> tasks = taskGroups.get(groupName);
if (tasks == null) {
return null;
}
for (Task task : tasks) {
if (!task.completed) {
task.complete();
return task.name;
}
}
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.thealgorithms.scheduling;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

public class SpeculativeExecutionSchedulingTest {

private SpeculativeExecutionScheduling scheduler;

@BeforeEach
public void setup() {
scheduler = new SpeculativeExecutionScheduling();
}

@Test
public void testAddAndExecuteTask() {
scheduler.addTask("Group1", "Task1");
assertEquals("Task1", scheduler.executeTasks("Group1"));
}

@Test
public void testMultipleTasksInGroup() {
scheduler.addTask("Group1", "Task1");
scheduler.addTask("Group1", "Task2");
assertEquals("Task1", scheduler.executeTasks("Group1"));
assertEquals("Task2", scheduler.executeTasks("Group1"));
}

@Test
public void testExecuteAllTasks() {
scheduler.addTask("Group1", "Task1");
scheduler.addTask("Group1", "Task2");
scheduler.executeTasks("Group1");
scheduler.executeTasks("Group1");
assertNull(scheduler.executeTasks("Group1"));
}

@Test
public void testEmptyTaskGroup() {
assertNull(scheduler.executeTasks("Group2"));
}
}