Added ReadWriteLock instead of synchronize for Rooms
This commit is contained in:
parent
bdf9616062
commit
c998da9792
@ -11,8 +11,9 @@ import ru.dragonestia.picker.repository.RoomRepository;
|
|||||||
import ru.dragonestia.picker.repository.UserRepository;
|
import ru.dragonestia.picker.repository.UserRepository;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
import java.util.concurrent.locks.ReadWriteLock;
|
||||||
|
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -20,13 +21,15 @@ public class RoomRepositoryImpl implements RoomRepository {
|
|||||||
|
|
||||||
private final UserRepository userRepository;
|
private final UserRepository userRepository;
|
||||||
private final PickerRepository pickerRepository;
|
private final PickerRepository pickerRepository;
|
||||||
private final Map<Node, Rooms> node2roomsMap = new ConcurrentHashMap<>();
|
private final Map<Node, Rooms> node2roomsMap = new HashMap<>();
|
||||||
|
private final ReadWriteLock lock = new ReentrantReadWriteLock();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create(Room room) throws RoomAlreadyExistException {
|
public void create(Room room) throws RoomAlreadyExistException {
|
||||||
var nodeId = room.getNodeIdentifier();
|
var nodeId = room.getNodeIdentifier();
|
||||||
|
|
||||||
synchronized (node2roomsMap) {
|
lock.writeLock().lock();
|
||||||
|
try {
|
||||||
var node = node2roomsMap.keySet().stream()
|
var node = node2roomsMap.keySet().stream()
|
||||||
.filter(n -> room.getNodeIdentifier().equals(n.getIdentifier()))
|
.filter(n -> room.getNodeIdentifier().equals(n.getIdentifier()))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
@ -41,6 +44,8 @@ public class RoomRepositoryImpl implements RoomRepository {
|
|||||||
}
|
}
|
||||||
rooms.put(room.getIdentifier(), new RoomContainer(room, new AtomicInteger(0)));
|
rooms.put(room.getIdentifier(), new RoomContainer(room, new AtomicInteger(0)));
|
||||||
pickerRepository.find(room.getNodeIdentifier()).add(room);
|
pickerRepository.find(room.getNodeIdentifier()).add(room);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,44 +56,54 @@ public class RoomRepositoryImpl implements RoomRepository {
|
|||||||
.filter(n -> room.getNodeIdentifier().equals(n.getIdentifier()))
|
.filter(n -> room.getNodeIdentifier().equals(n.getIdentifier()))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
|
|
||||||
synchronized (node2roomsMap) {
|
lock.writeLock().lock();
|
||||||
|
try {
|
||||||
if (node.isEmpty()) {
|
if (node.isEmpty()) {
|
||||||
throw new NodeNotFoundException("Node '" + nodeId + "' does not exist");
|
throw new NodeNotFoundException("Node '" + nodeId + "' does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
node2roomsMap.get(node.get()).remove(room.getIdentifier());
|
node2roomsMap.get(node.get()).remove(room.getIdentifier());
|
||||||
pickerRepository.find(room.getNodeIdentifier()).remove(room);
|
pickerRepository.find(room.getNodeIdentifier()).remove(room);
|
||||||
}
|
|
||||||
|
|
||||||
userRepository.onRemoveRoom(room);
|
userRepository.onRemoveRoom(room);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Room> find(Node node, String identifier) {
|
public Optional<Room> find(Node node, String identifier) {
|
||||||
synchronized (node2roomsMap) {
|
lock.readLock().lock();
|
||||||
|
try {
|
||||||
if (!node2roomsMap.containsKey(node)) {
|
if (!node2roomsMap.containsKey(node)) {
|
||||||
throw new NodeNotFoundException("Node '" + node.getIdentifier() + "' does not exist");
|
throw new NodeNotFoundException("Node '" + node.getIdentifier() + "' does not exist");
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = node2roomsMap.get(node).getOrDefault(identifier, null);
|
var result = node2roomsMap.get(node).getOrDefault(identifier, null);
|
||||||
return result == null? Optional.empty() : Optional.of(result.room());
|
return result == null? Optional.empty() : Optional.of(result.room());
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Room> all(Node node) {
|
public List<Room> all(Node node) {
|
||||||
synchronized (node2roomsMap) {
|
lock.readLock().lock();
|
||||||
|
try {
|
||||||
if (!node2roomsMap.containsKey(node)) {
|
if (!node2roomsMap.containsKey(node)) {
|
||||||
throw new NodeNotFoundException("Node '%s' does not exists".formatted(node.getIdentifier()));
|
throw new NodeNotFoundException("Node '%s' does not exists".formatted(node.getIdentifier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return node2roomsMap.get(node).values().stream().map(RoomContainer::room).toList();
|
return node2roomsMap.get(node).values().stream().map(RoomContainer::room).toList();
|
||||||
|
} finally {
|
||||||
|
lock.readLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Room> pickFree(Node node, Collection<User> users) {
|
public Optional<Room> pickFree(Node node, Collection<User> users) {
|
||||||
synchronized (node2roomsMap) {
|
lock.writeLock().lock();
|
||||||
|
try {
|
||||||
if (!node2roomsMap.containsKey(node)) {
|
if (!node2roomsMap.containsKey(node)) {
|
||||||
throw new NodeNotFoundException("Node '" + node.getIdentifier() + "' does not exist");
|
throw new NodeNotFoundException("Node '" + node.getIdentifier() + "' does not exist");
|
||||||
}
|
}
|
||||||
@ -109,24 +124,32 @@ public class RoomRepositoryImpl implements RoomRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return container.map(RoomContainer::room);
|
return container.map(RoomContainer::room);
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCreateNode(Node node) {
|
public void onCreateNode(Node node) {
|
||||||
synchronized (node2roomsMap) {
|
lock.writeLock().lock();
|
||||||
|
try {
|
||||||
node2roomsMap.put(node, new Rooms());
|
node2roomsMap.put(node, new Rooms());
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Room> onRemoveNode(Node node) {
|
public List<Room> onRemoveNode(Node node) {
|
||||||
List<Room> deleted;
|
lock.writeLock().lock();
|
||||||
synchronized (node2roomsMap) {
|
try {
|
||||||
deleted = node2roomsMap.get(node).values().stream().map(container -> container.room).toList();
|
var deleted = node2roomsMap.get(node).values().stream().map(container -> container.room).toList();
|
||||||
node2roomsMap.remove(node);
|
node2roomsMap.remove(node);
|
||||||
}
|
|
||||||
return deleted;
|
return deleted;
|
||||||
|
} finally {
|
||||||
|
lock.writeLock().unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record RoomContainer(Room room, AtomicInteger used) {
|
private record RoomContainer(Room room, AtomicInteger used) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user