import com.google.common.collect.HashMultimap
import com.google.common.collect.Multimap
import com.google.common.collect.TreeMultimap
-import com.google.common.util.concurrent.*
+import com.google.common.util.concurrent.AbstractService
+import com.google.common.util.concurrent.RateLimiter
import com.google.inject.Inject
import com.google.inject.Singleton
import net.pterodactylus.sone.data.Album
import net.pterodactylus.sone.data.Image
import net.pterodactylus.sone.data.Post
import net.pterodactylus.sone.data.PostReply
-import net.pterodactylus.sone.data.Reply.TIME_COMPARATOR
import net.pterodactylus.sone.data.Sone
import net.pterodactylus.sone.data.allAlbums
import net.pterodactylus.sone.data.allImages
import net.pterodactylus.sone.data.impl.AlbumBuilderImpl
import net.pterodactylus.sone.data.impl.ImageBuilderImpl
+import net.pterodactylus.sone.data.newestReplyFirst
import net.pterodactylus.sone.database.AlbumBuilder
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.utils.*
+import net.pterodactylus.sone.utils.ifTrue
+import net.pterodactylus.sone.utils.unit
import net.pterodactylus.util.config.Configuration
import net.pterodactylus.util.config.ConfigurationException
import java.util.concurrent.locks.ReentrantReadWriteLock
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock
import kotlin.concurrent.withLock
/**
class MemoryDatabase @Inject constructor(private val configuration: Configuration) : AbstractService(), Database {
private val lock = ReentrantReadWriteLock()
- private val readLock by lazy { lock.readLock()!! }
- private val writeLock by lazy { lock.writeLock()!! }
+ private val readLock: ReadLock by lazy { lock.readLock() }
+ private val writeLock: WriteLock by lazy { lock.writeLock() }
private val configurationLoader = ConfigurationLoader(configuration)
private val allSones = mutableMapOf<String, Sone>()
private val allPosts = mutableMapOf<String, Post>()
private val sonePosts: Multimap<String, Post> = HashMultimap.create<String, Post>()
private val knownPosts = mutableSetOf<String>()
- private val allPostReplies = mutableMapOf<String, PostReply>()
- private val sonePostReplies: Multimap<String, PostReply> = TreeMultimap.create<String, PostReply>(Comparator { leftString, rightString -> leftString.compareTo(rightString) }, TIME_COMPARATOR)
+ private val allPostReplies = mutableMapOf<String, MemoryPostReply.Shell>()
+ private val sonePostReplies: Multimap<String, PostReply> = TreeMultimap.create<String, PostReply>(Comparator { leftString, rightString -> leftString.compareTo(rightString) }, newestReplyFirst)
private val knownPostReplies = mutableSetOf<String>()
private val allAlbums = mutableMapOf<String, Album>()
private val soneAlbums: Multimap<String, Album> = HashMultimap.create<String, Album>()
}
sonePostReplies.putAll(sone.id, sone.replies)
for (postReply in sone.replies) {
- allPostReplies[postReply.id] = postReply
+ allPostReplies[postReply.id] = postReply.toShell()
}
sone.allAlbums.let { albums ->
soneAlbums.putAll(sone.id, albums)
}
}
- override fun getPostReply(id: String) = readLock.withLock { allPostReplies[id] }
+ override fun getPostReply(id: String) = readLock.withLock {
+ allPostReplies[id]?.build(newPostReplyBuilder())
+ }
override fun getReplies(postId: String) =
readLock.withLock {
allPostReplies.values
.filter { it.postId == postId }
- .sortedWith(TIME_COMPARATOR)
+ .map { it.build(newPostReplyBuilder()) }
+ .sortedWith(newestReplyFirst.reversed())
}
override fun newPostReplyBuilder(): PostReplyBuilder =
override fun storePostReply(postReply: PostReply) =
writeLock.withLock {
- allPostReplies[postReply.id] = postReply
+ allPostReplies[postReply.id] = postReply.toShell()
}
override fun removePostReply(postReply: PostReply) =
override fun isPostBookmarked(post: Post) =
memoryBookmarkDatabase.isPostBookmarked(post)
- protected fun isPostKnown(post: Post) = readLock.withLock { post.id in knownPosts }
+ internal fun isPostKnown(post: Post) = readLock.withLock { post.id in knownPosts }
fun setPostKnown(post: Post, known: Boolean): Unit =
writeLock.withLock {
saveKnownPosts()
}
- protected fun isPostReplyKnown(postReply: PostReply) = readLock.withLock { postReply.id in knownPostReplies }
+ internal fun isPostReplyKnown(postReply: PostReply) = readLock.withLock { postReply.id in knownPostReplies }
- fun setPostReplyKnown(postReply: PostReply, known: Boolean): Unit =
+ override fun setPostReplyKnown(postReply: PostReply): Unit =
writeLock.withLock {
- if (known)
- knownPostReplies.add(postReply.id)
- else
- knownPostReplies.remove(postReply.id)
+ knownPostReplies.add(postReply.id)
saveKnownPostReplies()
}