remove explicit compact - rely on autocompact during commit

GitOrigin-RevId: 6afa82986017cfd82d715714812ed3860b94aed7
This commit is contained in:
Vladimir Krivosheev
2024-07-24 07:43:50 +02:00
committed by intellij-monorepo-bot
parent 1e18c62013
commit 00ccbfef9d
6 changed files with 11 additions and 75 deletions

View File

@@ -8,10 +8,7 @@ import com.intellij.openapi.components.Service
import com.intellij.ui.svg.SvgCacheManager
import com.intellij.ui.svg.activeSvgCache
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.withContext
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
import kotlin.time.DurationUnit
import kotlin.time.toDuration
@@ -21,28 +18,20 @@ private fun nowAsDuration() = System.currentTimeMillis().toDuration(DurationUnit
// icons maybe loaded before app loaded, so, SvgCacheMapper cannot be as a service
@Service(Service.Level.APP)
internal class IconDbMaintainer : SettingsSavingComponent {
// save is ignored first 5 minutes
private var lastSaved: Duration = nowAsDuration()
// compact only once per-app launch
private var isCompacted = AtomicBoolean(false)
// we save only once every 2 minutes, and not earlier than 2 minutes after the start
private var lastSaved = nowAsDuration()
override suspend fun save() {
val exitInProgress = ApplicationManager.getApplication().isExitInProgress
if (!exitInProgress && (nowAsDuration() - lastSaved) < 5.minutes) {
if (!exitInProgress && (nowAsDuration() - lastSaved) < 2.minutes) {
return
}
val svgCache = activeSvgCache ?: return
withContext(Dispatchers.IO) {
svgCache.save()
ensureActive()
if (!exitInProgress && isCompacted.compareAndSet(false, true)) {
svgCache.compact()
}
lastSaved = nowAsDuration()
}
lastSaved = nowAsDuration()
}
}

View File

@@ -18,11 +18,6 @@ fun clearCacheStore() {
serviceIfCreated<InternalAndCacheStorageManager>()?.storeManager?.clear()
}
@TestOnly
internal fun compactCacheStore() {
serviceIfCreated<InternalAndCacheStorageManager>()?.storeManager?.compactStore()
}
private class LocalSettingsController : DelegatedSettingsController {
private val storageManager = SynchronizedClearableLazy { service<InternalAndCacheStorageManager>() }

View File

@@ -7,21 +7,15 @@ import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.components.StoragePathMacros
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.util.io.mvstore.compactMvStore
import com.intellij.util.io.mvstore.createOrResetMvStore
import com.intellij.util.io.mvstore.openOrResetMap
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ensureActive
import kotlinx.coroutines.withContext
import org.h2.mvstore.MVMap
import org.h2.mvstore.MVStore
import org.h2.mvstore.type.ByteArrayDataType
import org.jetbrains.annotations.TestOnly
import org.jetbrains.annotations.VisibleForTesting
import java.nio.file.Path
import java.util.concurrent.atomic.AtomicBoolean
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
import kotlin.time.DurationUnit
import kotlin.time.toDuration
@@ -29,43 +23,27 @@ import kotlin.time.toDuration
private fun nowAsDuration() = System.currentTimeMillis().toDuration(DurationUnit.MILLISECONDS)
internal class MvStoreManager(readOnly: Boolean = false) {
// yes - save is ignored first 5 minutes
private var lastSaved: Duration = nowAsDuration()
// compact only once per-app launch
private var isCompacted = AtomicBoolean(false)
private val store: MVStore = createOrResetMvStore(getDatabaseFile(), readOnly) { logger<MvMapManager>() }
// we save only once every 2 minutes, and not earlier than 2 minutes after the start
private var lastSaved = nowAsDuration()
private val store = createOrResetMvStore(getDatabaseFile(), readOnly) { logger<MvMapManager>() }
fun openMap(name: String): MvMapManager = MvMapManager(openMap(store, name))
suspend fun save() {
// Save upon exit.
// This function will be executed under progress.
// If saving is skipped here, 'close' would be invoked on `dispose`, which will trigger `save`.
// If saving is skipped here, `close` would be invoked on `close`, which will trigger `save`.
// This in turn would lead to saving in EDT — that must be avoided.
val exitInProgress = ApplicationManager.getApplication().isExitInProgress
if (!exitInProgress && (nowAsDuration() - lastSaved) < 5.minutes) {
if (!exitInProgress && (nowAsDuration() - lastSaved) < 2.minutes) {
return
}
// tryCommit - do not commit if store is locked (e.g., another commit for some reason is called or another write operation)
withContext(Dispatchers.IO) {
store.tryCommit()
ensureActive()
if (!exitInProgress && isCompacted.compareAndSet(false, true)) {
compactStore()
}
store.commit()
lastSaved = nowAsDuration()
}
lastSaved = nowAsDuration()
}
@VisibleForTesting
fun compactStore() {
compactMvStore(store, ::thisLogger)
}
fun close() {

View File

@@ -33,9 +33,6 @@ class LocalSettingsControllerTest {
assertThat(controller.getItem(settingsDescriptor)).isNull()
controller.setItem(settingsDescriptor, "test")
assertThat(controller.getItem(settingsDescriptor)).isEqualTo("test")
// test compact
compactCacheStore()
}
@Test

View File

@@ -6,11 +6,9 @@ import com.intellij.util.ArrayUtilRt
import org.h2.mvstore.MVMap
import org.h2.mvstore.MVStore
import org.jetbrains.annotations.ApiStatus.Internal
import java.nio.channels.ClosedChannelException
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
import kotlin.time.Duration.Companion.seconds
@Internal
fun markMvStoreDbAsInvalid(file: Path) {
@@ -101,18 +99,4 @@ private class StoreErrorHandler(private val dbFile: Path?, private val logSuppli
log.warn("Store will be recreated (db=$dbFile)", e)
}
}
}
@Internal
fun compactMvStore(store: MVStore, logSupplier: () -> Logger) {
try {
store.compactFile(3.seconds.inWholeMilliseconds.toInt())
}
catch (e: RuntimeException) {
/** see [org.h2.mvstore.FileStore.compact] */
val cause = e.cause
if (cause !is InterruptedException && cause !is ClosedChannelException) {
logSupplier().warn("Cannot compact", e)
}
}
}

View File

@@ -10,7 +10,6 @@ import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.diagnostic.thisLogger
import com.intellij.util.ArrayUtilRt
import com.intellij.util.InsecureHashBuilder
import com.intellij.util.io.mvstore.compactMvStore
import com.intellij.util.io.mvstore.createOrResetMvStore
import com.intellij.util.io.mvstore.markMvStoreDbAsInvalid
import com.intellij.util.io.mvstore.openOrResetMap
@@ -151,12 +150,6 @@ class SvgCacheManager private constructor(
}
}
fun compact() {
if (!map.isClosed) {
compactMvStore(map.store, ::thisLogger)
}
}
fun markCorrupted() {
thisLogger().info("invalidate and disable icon cache")
invalidateCache()