Use a multimap to store the posts for a Sone.
[Sone.git] / src / main / java / net / pterodactylus / sone / database / memory / MemoryDatabase.java
index 00443e4..a19290e 100644 (file)
@@ -46,17 +46,19 @@ import net.pterodactylus.sone.data.Reply;
 import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.sone.database.Database;
 import net.pterodactylus.sone.database.DatabaseException;
-import net.pterodactylus.sone.database.PostBuilder;
 import net.pterodactylus.sone.database.PostDatabase;
-import net.pterodactylus.sone.database.PostReplyBuilder;
 import net.pterodactylus.sone.database.SoneBuilder;
+import net.pterodactylus.sone.freenet.wot.Identity;
 import net.pterodactylus.util.config.Configuration;
 import net.pterodactylus.util.config.ConfigurationException;
 
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.collect.ArrayListMultimap;
+import com.google.common.collect.HashMultimap;
 import com.google.common.collect.ListMultimap;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Multimap;
 import com.google.common.collect.SortedSetMultimap;
 import com.google.common.collect.TreeMultimap;
 import com.google.common.util.concurrent.AbstractService;
@@ -75,13 +77,14 @@ public class MemoryDatabase extends AbstractService implements Database {
        /** The configuration. */
        private final Configuration configuration;
 
+       private final Map<String, Identity> identities = Maps.newHashMap();
        private final Map<String, Sone> sones = new HashMap<String, Sone>();
 
        /** All posts by their ID. */
        private final Map<String, Post> allPosts = new HashMap<String, Post>();
 
        /** All posts by their Sones. */
-       private final Map<String, Collection<Post>> sonePosts = new HashMap<String, Collection<Post>>();
+       private final Multimap<String, Post> sonePosts = HashMultimap.create();
 
        /** All posts by their recipient. */
        private final Map<String, Collection<Post>> recipientPosts = new HashMap<String, Collection<Post>>();
@@ -128,12 +131,6 @@ public class MemoryDatabase extends AbstractService implements Database {
        // DATABASE METHODS
        //
 
-       /**
-        * Saves the database.
-        *
-        * @throws DatabaseException
-        *              if an error occurs while saving
-        */
        @Override
        public void save() throws DatabaseException {
                saveKnownPosts();
@@ -144,7 +141,6 @@ public class MemoryDatabase extends AbstractService implements Database {
        // SERVICE METHODS
        //
 
-       /** {@inheritDocs} */
        @Override
        protected void doStart() {
                loadKnownPosts();
@@ -152,7 +148,6 @@ public class MemoryDatabase extends AbstractService implements Database {
                notifyStarted();
        }
 
-       /** {@inheritDocs} */
        @Override
        protected void doStop() {
                try {
@@ -164,6 +159,16 @@ public class MemoryDatabase extends AbstractService implements Database {
        }
 
        @Override
+       public Optional<Identity> getIdentity(String identityId) {
+               lock.readLock().lock();
+               try {
+                       return fromNullable(identities.get(identityId));
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
+       @Override
        public Optional<Sone> getSone(String soneId) {
                lock.readLock().lock();
                try {
@@ -212,7 +217,6 @@ public class MemoryDatabase extends AbstractService implements Database {
        // POSTPROVIDER METHODS
        //
 
-       /** {@inheritDocs} */
        @Override
        public Optional<Post> getPost(String postId) {
                lock.readLock().lock();
@@ -223,13 +227,16 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public Collection<Post> getPosts(String soneId) {
-               return new HashSet<Post>(getPostsFrom(soneId));
+               lock.readLock().lock();
+               try {
+                       return new HashSet<Post>(sonePosts.get(soneId));
+               } finally {
+                       lock.readLock().unlock();
+               }
        }
 
-       /** {@inheritDocs} */
        @Override
        public Collection<Post> getDirectedPosts(String recipientId) {
                lock.readLock().lock();
@@ -245,14 +252,13 @@ public class MemoryDatabase extends AbstractService implements Database {
        // POSTSTORE METHODS
        //
 
-       /** {@inheritDocs} */
        @Override
        public void storePost(Post post) {
                checkNotNull(post, "post must not be null");
                lock.writeLock().lock();
                try {
                        allPosts.put(post.getId(), post);
-                       getPostsFrom(post.getSone().getId()).add(post);
+                       sonePosts.put(post.getSone().getId(), post);
                        if (post.getRecipientId().isPresent()) {
                                getPostsTo(post.getRecipientId().get()).add(post);
                        }
@@ -261,14 +267,13 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public void removePost(Post post) {
                checkNotNull(post, "post must not be null");
                lock.writeLock().lock();
                try {
                        allPosts.remove(post.getId());
-                       getPostsFrom(post.getSone().getId()).remove(post);
+                       sonePosts.remove(post.getSone().getId(), post);
                        if (post.getRecipientId().isPresent()) {
                                getPostsTo(post.getRecipientId().get()).remove(post);
                        }
@@ -278,7 +283,6 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public void storePosts(Sone sone, Collection<Post> posts) throws IllegalArgumentException {
                checkNotNull(sone, "sone must not be null");
@@ -292,7 +296,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                lock.writeLock().lock();
                try {
                        /* remove all posts by the Sone. */
-                       getPostsFrom(sone.getId()).clear();
+                       sonePosts.removeAll(sone.getId());
                        for (Post post : posts) {
                                allPosts.remove(post.getId());
                                if (post.getRecipientId().isPresent()) {
@@ -301,7 +305,7 @@ public class MemoryDatabase extends AbstractService implements Database {
                        }
 
                        /* add new posts. */
-                       getPostsFrom(sone.getId()).addAll(posts);
+                       sonePosts.putAll(sone.getId(), posts);
                        for (Post post : posts) {
                                allPosts.put(post.getId(), post);
                                if (post.getRecipientId().isPresent()) {
@@ -313,14 +317,13 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public void removePosts(Sone sone) {
                checkNotNull(sone, "sone must not be null");
                lock.writeLock().lock();
                try {
                        /* remove all posts by the Sone. */
-                       getPostsFrom(sone.getId()).clear();
+                       sonePosts.removeAll(sone.getId());
                        for (Post post : sone.getPosts()) {
                                allPosts.remove(post.getId());
                                if (post.getRecipientId().isPresent()) {
@@ -336,7 +339,6 @@ public class MemoryDatabase extends AbstractService implements Database {
        // POSTREPLYPROVIDER METHODS
        //
 
-       /** {@inheritDocs} */
        @Override
        public Optional<PostReply> getPostReply(String id) {
                lock.readLock().lock();
@@ -347,7 +349,6 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public List<PostReply> getReplies(String postId) {
                lock.readLock().lock();
@@ -365,7 +366,33 @@ public class MemoryDatabase extends AbstractService implements Database {
        // POSTREPLYSTORE METHODS
        //
 
-       /** {@inheritDocs} */
+       /**
+        * Returns whether the given post reply is known.
+        *
+        * @param postReply
+        *              The post reply
+        * @return {@code true} if the given post reply is known, {@code false}
+        *         otherwise
+        */
+       public boolean isPostReplyKnown(PostReply postReply) {
+               lock.readLock().lock();
+               try {
+                       return knownPostReplies.contains(postReply.getId());
+               } finally {
+                       lock.readLock().unlock();
+               }
+       }
+
+       @Override
+       public void setPostReplyKnown(PostReply postReply) {
+               lock.writeLock().lock();
+               try {
+                       knownPostReplies.add(postReply.getId());
+               } finally {
+                       lock.writeLock().unlock();
+               }
+       }
+
        @Override
        public void storePostReply(PostReply postReply) {
                lock.writeLock().lock();
@@ -383,7 +410,6 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public void storePostReplies(Sone sone, Collection<PostReply> postReplies) {
                checkNotNull(sone, "sone must not be null");
@@ -416,7 +442,6 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public void removePostReply(PostReply postReply) {
                lock.writeLock().lock();
@@ -433,7 +458,6 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /** {@inheritDocs} */
        @Override
        public void removePostReplies(Sone sone) {
                checkNotNull(sone, "sone must not be null");
@@ -653,80 +677,11 @@ public class MemoryDatabase extends AbstractService implements Database {
                }
        }
 
-       /**
-        * Returns whether the given post reply is known.
-        *
-        * @param postReply
-        *              The post reply
-        * @return {@code true} if the given post reply is known, {@code false}
-        *         otherwise
-        */
-       boolean isPostReplyKnown(PostReply postReply) {
-               lock.readLock().lock();
-               try {
-                       return knownPostReplies.contains(postReply.getId());
-               } finally {
-                       lock.readLock().unlock();
-               }
-       }
-
-       /**
-        * Sets whether the given post reply is known.
-        *
-        * @param postReply
-        *              The post reply
-        * @param known
-        *              {@code true} if the post reply is known, {@code false} otherwise
-        */
-       void setPostReplyKnown(PostReply postReply, boolean known) {
-               lock.writeLock().lock();
-               try {
-                       if (known) {
-                               knownPostReplies.add(postReply.getId());
-                       } else {
-                               knownPostReplies.remove(postReply.getId());
-                       }
-               } finally {
-                       lock.writeLock().unlock();
-               }
-       }
-
        //
        // PRIVATE METHODS
        //
 
        /**
-        * Gets all posts for the given Sone, creating a new collection if there is
-        * none yet.
-        *
-        * @param soneId
-        *              The ID of the Sone to get the posts for
-        * @return All posts
-        */
-       private Collection<Post> getPostsFrom(String soneId) {
-               Collection<Post> posts = null;
-               lock.readLock().lock();
-               try {
-                       posts = sonePosts.get(soneId);
-               } finally {
-                       lock.readLock().unlock();
-               }
-               if (posts != null) {
-                       return posts;
-               }
-
-               posts = new HashSet<Post>();
-               lock.writeLock().lock();
-               try {
-                       sonePosts.put(soneId, posts);
-               } finally {
-                       lock.writeLock().unlock();
-               }
-
-               return posts;
-       }
-
-       /**
         * Gets all posts that are directed the given Sone, creating a new collection
         * if there is none yet.
         *