Fixed bug with infinite looped iteration in QueuedLinkedList

This commit is contained in:
Andrey Terentev 2024-01-12 16:53:53 +07:00
parent 022fcd2abf
commit efd53e6954
2 changed files with 34 additions and 4 deletions

View File

@ -2,14 +2,24 @@ package ru.dragonestia.picker.repository.impl.collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class QueuedLinkedList<ITEM extends QueuedLinkedList.Item> {
private final Function<ITEM, Boolean> selectorValidator;
private Node<ITEM> first;
private Node<ITEM> last;
private Node<ITEM> cursor;
private final Map<String, Node<ITEM>> itemMap = new HashMap<>();
public QueuedLinkedList() {
this(item -> true);
}
public QueuedLinkedList(Function<ITEM, Boolean> selectorValidator) {
this.selectorValidator = selectorValidator;
}
public void add(ITEM item) {
if (itemMap.containsKey(item.getId())) return;
@ -77,11 +87,28 @@ public class QueuedLinkedList<ITEM extends QueuedLinkedList.Item> {
if (cursor == null) cursor = first;
int rounds = 0;
Node<ITEM> item = cursor;
while (item != null && item.removed) {
while(rounds < 1) {
while (item != null && item.removed) {
item = item.next;
}
if (item == null) {
item = first;
rounds++;
continue;
}
if (selectorValidator.apply(item.object)) {
break;
}
item = item.next;
}
if (item == null) item = first;
if (rounds > 0) {
throw new RuntimeException("Cannot get need object because no one fulfills all the conditions");
}
cursor = item.next;
return item.object;

View File

@ -7,11 +7,13 @@ import ru.dragonestia.picker.repository.UserRepository;
import ru.dragonestia.picker.repository.impl.collection.QueuedLinkedList;
import java.util.Collection;
import java.util.concurrent.atomic.AtomicInteger;
public class RoundRobinPicker implements RoomPicker {
private final UserRepository userRepository;
private final QueuedLinkedList<RoomWrapper> list = new QueuedLinkedList<>();
private final AtomicInteger addition = new AtomicInteger(0);
private final QueuedLinkedList<RoomWrapper> list = new QueuedLinkedList<>(wrapper -> wrapper.canAddUnits(addition.get()));
public RoundRobinPicker(UserRepository userRepository) {
this.userRepository = userRepository;
@ -38,7 +40,8 @@ public class RoundRobinPicker implements RoomPicker {
synchronized (list) {
try {
while (!(wrapper = list.pick()).canAddUnits(amount));
addition.set(amount);
wrapper = list.pick();
} catch (RuntimeException ex) {
throw new RuntimeException("There are no rooms available");
}