1 package net.pterodactylus.sone.database.memory;
3 import java.util.Collection;
4 import java.util.HashMap;
6 import java.util.concurrent.locks.ReadWriteLock;
7 import java.util.concurrent.locks.ReentrantReadWriteLock;
9 import com.google.common.base.Optional;
10 import com.google.common.collect.HashMultimap;
11 import com.google.common.collect.Multimap;
14 * In-memory implementation of friend-related functionality.
16 * @author <a href="mailto:bombe@pterodactylus.net">David ‘Bombe’ Roden</a>
18 class MemoryFriendDatabase {
20 private final ReadWriteLock lock = new ReentrantReadWriteLock();
21 private final ConfigurationLoader configurationLoader;
22 private final Multimap<String, String> soneFriends = HashMultimap.create();
23 private final Map<String, Long> soneFollowingTimes = new HashMap<String, Long>();
25 MemoryFriendDatabase(ConfigurationLoader configurationLoader) {
26 this.configurationLoader = configurationLoader;
30 loadSoneFollowingTimes();
33 private void loadSoneFollowingTimes() {
34 Map<String, Long> soneFollowingTimes = configurationLoader.loadSoneFollowingTimes();
35 lock.writeLock().lock();
37 this.soneFollowingTimes.clear();
38 this.soneFollowingTimes.putAll(soneFollowingTimes);
40 lock.writeLock().unlock();
45 saveSoneFollowingTimes();
48 private void saveSoneFollowingTimes() {
49 lock.readLock().lock();
51 configurationLoader.saveSoneFollowingTimes(soneFollowingTimes);
53 lock.readLock().unlock();
57 Collection<String> getFriends(String localSoneId) {
58 loadFriends(localSoneId);
59 lock.readLock().lock();
61 return soneFriends.get(localSoneId);
63 lock.readLock().unlock();
67 Optional<Long> getSoneFollowingTime(String soneId) {
68 lock.readLock().lock();
70 return Optional.fromNullable(soneFollowingTimes.get(soneId));
72 lock.readLock().unlock();
76 boolean isFriend(String localSoneId, String friendSoneId) {
77 loadFriends(localSoneId);
78 lock.readLock().lock();
80 return soneFriends.containsEntry(localSoneId, friendSoneId);
82 lock.readLock().unlock();
86 void addFriend(String localSoneId, String friendSoneId) {
87 loadFriends(localSoneId);
88 lock.writeLock().lock();
90 if (!soneFollowingTimes.containsKey(friendSoneId)) {
91 soneFollowingTimes.put(friendSoneId, System.currentTimeMillis());
92 saveSoneFollowingTimes();
94 if (soneFriends.put(localSoneId, friendSoneId)) {
95 configurationLoader.saveFriends(localSoneId, soneFriends.get(localSoneId));
98 lock.writeLock().unlock();
102 void removeFriend(String localSoneId, String friendSoneId) {
103 loadFriends(localSoneId);
104 lock.writeLock().lock();
106 if (soneFriends.remove(localSoneId, friendSoneId)) {
107 if (!soneFriends.containsValue(friendSoneId)) {
108 soneFollowingTimes.remove(friendSoneId);
109 saveSoneFollowingTimes();
111 configurationLoader.saveFriends(localSoneId, soneFriends.get(localSoneId));
114 lock.writeLock().unlock();
118 private void loadFriends(String localSoneId) {
119 lock.writeLock().lock();
121 if (soneFriends.containsKey(localSoneId)) {
124 soneFriends.putAll(localSoneId, configurationLoader.loadFriends(localSoneId));
126 lock.writeLock().unlock();