build.gradle.kts: tests and docs for LastModifiedFiles collection

This commit is contained in:
Sergey Rostov
2020-01-09 11:38:42 +03:00
parent 4cf8203ce7
commit a339e7af19
3 changed files with 125 additions and 31 deletions
@@ -14,6 +14,8 @@ import com.intellij.openapi.vfs.newvfs.BulkFileListener
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import com.intellij.util.PathUtil
import org.jetbrains.annotations.TestOnly
import org.junit.Assert.assertEquals
import org.junit.Test
@State(
name = "KotlinBuildScriptsModificationInfo",
@@ -44,43 +46,17 @@ class GradleScriptInputsWatcher(val project: Project) : PersistentStateComponent
return storage.lastModifiedTimeStampExcept(file) < timeStamp
}
class Storage(
private var lastModifiedTS: Long = 0,
private var lastModifiedFiles: MutableSet<String> = hashSetOf(),
private var previousModifiedTS: Long = 0,
private var previousModifiedFiles: MutableSet<String> = hashSetOf()
) {
class Storage {
private val lastModifiedFiles = LastModifiedFiles()
fun lastModifiedTimeStampExcept(file: VirtualFile): Long {
val fileId = getFileId(file)
synchronized(this) {
if (lastModifiedFiles.contains(fileId) && lastModifiedFiles.size == 1) {
return previousModifiedTS
}
return lastModifiedTS
}
return lastModifiedFiles.lastModifiedTimeStampExcept(fileId)
}
fun fileChanged(file: VirtualFile, ts: Long) {
val fileId = getFileId(file)
synchronized(this) {
when {
ts > lastModifiedTS -> {
previousModifiedFiles = lastModifiedFiles
previousModifiedTS = lastModifiedTS
lastModifiedFiles = hashSetOf(fileId)
lastModifiedTS = ts
}
ts == lastModifiedTS -> {
lastModifiedFiles.add(fileId)
}
ts == previousModifiedTS -> {
previousModifiedFiles.add(fileId)
}
else -> {}
}
}
lastModifiedFiles.fileChanged(ts, fileId)
}
private fun getFileId(file: VirtualFile): String {
@@ -0,0 +1,43 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.scripting.gradle
/**
* Optimized collection for storing last modified files with ability to
* get time of last modified file expect given one ([lastModifiedTimeStampExcept]).
*
* This is required since Gradle scripts configurations should be updated on
* each other script changes (but not on the given script changes itself).
*
* Actually works by storing two last timestamps with the set of files modified at this times.
*/
class LastModifiedFiles {
private var last: SimultaneouslyChangedFiles = SimultaneouslyChangedFiles()
private var previous: SimultaneouslyChangedFiles = SimultaneouslyChangedFiles()
class SimultaneouslyChangedFiles(
val ts: Long = Long.MIN_VALUE,
val fileIds: MutableSet<String> = mutableSetOf()
)
@Synchronized
fun fileChanged(ts: Long, fileId: String) {
when {
ts > last.ts -> {
previous = last
last = SimultaneouslyChangedFiles(ts, hashSetOf(fileId))
}
ts == last.ts -> last.fileIds.add(fileId)
ts == previous.ts -> previous.fileIds.add(fileId)
}
}
@Synchronized
fun lastModifiedTimeStampExcept(fileId: String): Long = when {
last.fileIds.size == 1 && last.fileIds.contains(fileId) -> previous.ts
else -> last.ts
}
}
@@ -0,0 +1,75 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.idea.scripting.gradle
import org.junit.Test
import kotlin.test.assertEquals
class LastModifiedFilesTest {
val files = LastModifiedFiles()
@Test
fun testSimple0() {
assertEquals(Long.MIN_VALUE, files.lastModifiedTimeStampExcept("x"))
}
@Test
fun testSimple1() {
files.fileChanged(1, "x")
assertEquals(Long.MIN_VALUE, files.lastModifiedTimeStampExcept("x"))
assertEquals(1, files.lastModifiedTimeStampExcept("y"))
}
@Test
fun testSimple2() {
files.fileChanged(1, "x")
files.fileChanged(2, "y")
assertEquals(2, files.lastModifiedTimeStampExcept("x"))
assertEquals(1, files.lastModifiedTimeStampExcept("y"))
}
@Test
fun testSimple3() {
files.fileChanged(1, "x")
files.fileChanged(2, "y")
files.fileChanged(3, "z")
assertEquals(3, files.lastModifiedTimeStampExcept("x"))
assertEquals(3, files.lastModifiedTimeStampExcept("y"))
assertEquals(2, files.lastModifiedTimeStampExcept("z"))
}
@Test
fun testSame2() {
files.fileChanged(1, "x")
files.fileChanged(1, "y")
assertEquals(1, files.lastModifiedTimeStampExcept("x"))
assertEquals(1, files.lastModifiedTimeStampExcept("y"))
}
@Test
fun testSame3() {
files.fileChanged(1, "x")
files.fileChanged(1, "y")
files.fileChanged(2, "z")
assertEquals(2, files.lastModifiedTimeStampExcept("x"))
assertEquals(2, files.lastModifiedTimeStampExcept("y"))
assertEquals(1, files.lastModifiedTimeStampExcept("z"))
}
@Test
fun testSame4() {
files.fileChanged(1, "x")
files.fileChanged(1, "y")
files.fileChanged(2, "z")
files.fileChanged(3, "a")
files.fileChanged(3, "b")
assertEquals(3, files.lastModifiedTimeStampExcept("x"))
assertEquals(3, files.lastModifiedTimeStampExcept("y"))
assertEquals(3, files.lastModifiedTimeStampExcept("z"))
assertEquals(3, files.lastModifiedTimeStampExcept("a"))
assertEquals(3, files.lastModifiedTimeStampExcept("b"))
}
}