/*
- * Sone - MemoryDatabase.java - Copyright © 2013–2016 David Roden
+ * Sone - MemoryDatabase.kt - Copyright © 2013–2020 David Roden
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
import com.google.common.collect.HashMultimap
import com.google.common.collect.Multimap
import com.google.common.collect.TreeMultimap
-import com.google.common.util.concurrent.AbstractService
+import com.google.common.util.concurrent.*
import com.google.inject.Inject
import com.google.inject.Singleton
import net.pterodactylus.sone.data.Album
import net.pterodactylus.sone.database.PostBuilder
import net.pterodactylus.sone.database.PostDatabase
import net.pterodactylus.sone.database.PostReplyBuilder
-import net.pterodactylus.sone.utils.unit
+import net.pterodactylus.sone.utils.*
import net.pterodactylus.util.config.Configuration
import net.pterodactylus.util.config.ConfigurationException
import java.util.concurrent.locks.ReentrantReadWriteLock
private val soneImages: Multimap<String, Image> = HashMultimap.create<String, Image>()
private val memoryBookmarkDatabase = MemoryBookmarkDatabase(this, configurationLoader)
private val memoryFriendDatabase = MemoryFriendDatabase(configurationLoader)
+ private val saveRateLimiter: RateLimiter = RateLimiter.create(1.0)
+ private val saveKnownPostsRateLimiter: RateLimiter = RateLimiter.create(1.0)
+ private val saveKnownPostRepliesRateLimiter: RateLimiter = RateLimiter.create(1.0)
override val soneLoader get() = this::getSone
override val bookmarkedPosts get() = memoryBookmarkDatabase.bookmarkedPosts
override fun save() {
- saveKnownPosts()
- saveKnownPostReplies()
+ if (saveRateLimiter.tryAcquire()) {
+ saveKnownPosts()
+ saveKnownPostReplies()
+ }
}
override fun doStart() {
protected fun isPostKnown(post: Post) = readLock.withLock { post.id in knownPosts }
- protected fun setPostKnown(post: Post, known: Boolean): Unit =
+ fun setPostKnown(post: Post, known: Boolean): Unit =
writeLock.withLock {
if (known)
knownPosts.add(post.id)
else
knownPosts.remove(post.id)
+ saveKnownPosts()
}
protected fun isPostReplyKnown(postReply: PostReply) = readLock.withLock { postReply.id in knownPostReplies }
- protected fun setPostReplyKnown(postReply: PostReply, known: Boolean): Unit =
+ fun setPostReplyKnown(postReply: PostReply, known: Boolean): Unit =
writeLock.withLock {
if (known)
knownPostReplies.add(postReply.id)
else
knownPostReplies.remove(postReply.id)
+ saveKnownPostReplies()
}
private fun loadKnownPosts() =
}
private fun saveKnownPosts() =
- try {
- readLock.withLock {
- knownPosts.forEachIndexed { index, knownPostId ->
- configuration.getStringValue("KnowsPosts/$index/ID").value = knownPostId
+ saveKnownPostsRateLimiter.tryAcquire().ifTrue {
+ try {
+ readLock.withLock {
+ knownPosts.forEachIndexed { index, knownPostId ->
+ configuration.getStringValue("KnownPosts/$index/ID").value = knownPostId
+ }
+ configuration.getStringValue("KnownPosts/${knownPosts.size}/ID").value = null
}
- configuration.getStringValue("KnownPosts/${knownPosts.size}/ID").value = null
+ } catch (ce1: ConfigurationException) {
+ throw DatabaseException("Could not save database.", ce1)
}
- } catch (ce1: ConfigurationException) {
- throw DatabaseException("Could not save database.", ce1)
}
private fun loadKnownPostReplies(): Unit =
}
private fun saveKnownPostReplies() =
- try {
- readLock.withLock {
- knownPostReplies.forEachIndexed { index, knownPostReply ->
- configuration.getStringValue("KnownReplies/$index/ID").value = knownPostReply
+ saveKnownPostRepliesRateLimiter.tryAcquire().ifTrue {
+ try {
+ readLock.withLock {
+ knownPostReplies.forEachIndexed { index, knownPostReply ->
+ configuration.getStringValue("KnownReplies/$index/ID").value = knownPostReply
+ }
+ configuration.getStringValue("KnownReplies/${knownPostReplies.size}/ID").value = null
}
- configuration.getStringValue("KnownReplies/${knownPostReplies.size}/ID").value = null
+ } catch (ce1: ConfigurationException) {
+ throw DatabaseException("Could not save database.", ce1)
}
- } catch (ce1: ConfigurationException) {
- throw DatabaseException("Could not save database.", ce1)
}
}