1 package net.pterodactylus.sone.database.memory;
3 import java.util.Collection;
4 import java.util.concurrent.locks.ReadWriteLock;
5 import java.util.concurrent.locks.ReentrantReadWriteLock;
7 import javax.annotation.Nonnull;
8 import javax.annotation.Nullable;
10 import com.google.common.collect.HashMultimap;
11 import com.google.common.collect.Multimap;
14 * In-memory implementation of friend-related functionality.
16 class MemoryFriendDatabase {
18 private final ReadWriteLock lock = new ReentrantReadWriteLock();
19 private final ConfigurationLoader configurationLoader;
20 private final Multimap<String, String> soneFriends = HashMultimap.create();
22 MemoryFriendDatabase(ConfigurationLoader configurationLoader) {
23 this.configurationLoader = configurationLoader;
26 Collection<String> getFriends(String localSoneId) {
27 loadFriends(localSoneId);
28 lock.readLock().lock();
30 return soneFriends.get(localSoneId);
32 lock.readLock().unlock();
36 boolean isFriend(String localSoneId, String friendSoneId) {
37 loadFriends(localSoneId);
38 lock.readLock().lock();
40 return soneFriends.containsEntry(localSoneId, friendSoneId);
42 lock.readLock().unlock();
46 void addFriend(String localSoneId, String friendSoneId) {
47 loadFriends(localSoneId);
48 lock.writeLock().lock();
50 if (soneFriends.put(localSoneId, friendSoneId)) {
51 configurationLoader.saveFriends(localSoneId, soneFriends.get(localSoneId));
52 if (configurationLoader.getSoneFollowingTime(friendSoneId) == null) {
53 configurationLoader.setSoneFollowingTime(friendSoneId, System.currentTimeMillis());
57 lock.writeLock().unlock();
61 void removeFriend(String localSoneId, String friendSoneId) {
62 loadFriends(localSoneId);
63 lock.writeLock().lock();
65 if (soneFriends.remove(localSoneId, friendSoneId)) {
66 configurationLoader.saveFriends(localSoneId, soneFriends.get(localSoneId));
67 boolean unfollowedSoneStillFollowed = false;
68 for (String soneId : soneFriends.keys()) {
69 unfollowedSoneStillFollowed |= getFriends(soneId).contains(friendSoneId);
71 if (!unfollowedSoneStillFollowed) {
72 configurationLoader.removeSoneFollowingTime(friendSoneId);
76 lock.writeLock().unlock();
81 Long getFollowingTime(@Nonnull String soneId) {
82 return configurationLoader.getSoneFollowingTime(soneId);
85 private void loadFriends(String localSoneId) {
86 lock.writeLock().lock();
88 if (soneFriends.containsKey(localSoneId)) {
91 soneFriends.putAll(localSoneId, configurationLoader.loadFriends(localSoneId));
93 lock.writeLock().unlock();