Implemented SequentialFillingPicker

This commit is contained in:
Andrey Terentev 2024-01-11 18:01:58 +07:00
parent c551c01be8
commit 52039e9804
5 changed files with 128 additions and 1 deletions

View File

@ -7,7 +7,7 @@ import java.beans.Transient;
@Getter @Getter
public class SlotLimit { public class SlotLimit {
private final static int UNLIMITED_VALUE = -1; public final static int UNLIMITED_VALUE = -1;
private final int slots; private final int slots;

View File

@ -0,0 +1,26 @@
package ru.dragonestia.picker.service.impl.picker;
import ru.dragonestia.picker.model.type.SlotLimit;
public interface ItemWrapper<ITEM> {
String getIdentifier();
int countUnits();
int maxUnits();
default boolean isFull() {
return maxUnits() != SlotLimit.UNLIMITED_VALUE && countUnits() >= maxUnits();
}
default boolean isEmpty() {
return countUnits() == 0;
}
default boolean canAddUnits(int amount) {
return maxUnits() == SlotLimit.UNLIMITED_VALUE || countUnits() + amount < maxUnits();
}
ITEM getItem();
}

View File

@ -0,0 +1,12 @@
package ru.dragonestia.picker.service.impl.picker;
import java.util.Collection;
public interface Picker<ITEM, UNIT> {
void add(ITEM item);
void remove(ITEM item);
ITEM pick(Collection<UNIT> units);
}

View File

@ -0,0 +1,41 @@
package ru.dragonestia.picker.service.impl.picker;
import ru.dragonestia.picker.model.Room;
import java.util.function.Supplier;
public class RoomWrapper implements ItemWrapper<Room> {
private final Room room;
private final Supplier<Integer> userCountSupplier;
public RoomWrapper(Room room, Supplier<Integer> userCountSupplier) {
this.room = room;
this.userCountSupplier = userCountSupplier;
}
@Override
public String getIdentifier() {
return room.getId();
}
@Override
public int countUnits() {
return userCountSupplier.get();
}
@Override
public int maxUnits() {
return room.getSlots().getSlots();
}
@Override
public Room getItem() {
return room;
}
@Override
public boolean canAddUnits(int amount) {
return ItemWrapper.super.canAddUnits(amount) && !room.isLocked();
}
}

View File

@ -0,0 +1,48 @@
package ru.dragonestia.picker.service.impl.picker;
import ru.dragonestia.picker.model.Room;
import ru.dragonestia.picker.model.User;
import ru.dragonestia.picker.repository.UserRepository;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
public class SequentialFillingPicker implements Picker<Room, User> {
private final UserRepository userRepository;
private final Map<String, RoomWrapper> wrappers = new LinkedHashMap<>();
public SequentialFillingPicker(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Override
public void add(Room room) {
synchronized (wrappers) {
wrappers.put(room.getId(), new RoomWrapper(room, () -> userRepository.usersOf(room).size()));
}
}
@Override
public void remove(Room room) {
synchronized (wrappers) {
wrappers.remove(room.getId());
}
}
@Override
public Room pick(Collection<User> users) {
int amount = users.size();
synchronized (wrappers) {
for (var wrapper: wrappers.values()) {
if (wrapper.canAddUnits(amount)) continue;
return wrapper.getItem();
}
}
throw new RuntimeException("There are no rooms available");
}
}