More caches, better and generic cache code. Now Dracon listen to file changes to drop cached data. Implemented caches: - File contents in specific revision (never dropped) - Pijul ls and Pijul diff results - File Revision and File changes by patch - some others.. Dracon is incredible fast now, but still will take some time for bigger repos.
[?]
Apr 3, 2021, 3:18 AM
ISO7J5ZH5UB7NFZKTKKJQHQHCP4DWQ3F7SM2NDMVYJAGGIKDLX4QCDependencies
- [2]
Q35OTML2Remove use of coroutines, which was blocking IntelliJ UI in larger repositories Improvements for bigger repositories, now Dracon caches the changes that happened in a revision in a file, so everytime Dracon needs to query the changes of a revision, it loads directly from memory instead of doing a full-scan in Pijul repository. For tiny projects it is not a problem, but for medium ones it takes more than five minutes to scan the entire repository (and it was tested with a repo of only 700 records, however there was changes that had more than 60.000 lines). The cache file is saved in IntelliJ Data Path (project specific) and is compressed with gzip, so it will not use so much disk space (the cost worths the gains). - [3]
FNNW5IEAAdded more plugin files to Pijul - [4]
EAGIDXOLBuild 2 to only listen to changes in project under pijul - [5]
QXUEMZ3BInitial CahngeProvider - [6]
GGYFPXNDInitial plugin - [7]
MTPTFTHGInitial plugin 2 - [8]
7L5LODGZParse changes from `pijul change` - [9]
6CR2EFUNFirst ChangeProvider implementation!!! Wheehooo - [10]
OPFG6CZ2File status tracking supported. - [11]
FRFFQV7VBasic show history support. - [12]
ZCRW57C5Improved support for revisions - [13]
5AUENX2YAdd support to view files affected by a revision - [14]
NTRPUMVQImproved README and added roadmap. - [15]
B43WNBLF- Add Show History to Pijul menu - Always ignore .idea and .pijul in tracking. - Make findPijul a generic function to allow to find editor-server. - Only show one revision for directories. - Add `Hunk::resolvePath(Path)` to resolve the affected file to a Java NIO Path. - Fix StringOutOfBounds in Change Parsering Algorithm - Use editor-server instead of copie for interfacing with `pijul record` file. - Fix FileStatus provider not returning correctly for untracked files. - Add CommittedChangesProvider for Pijul. - [16]
Q7FXTHVUFirst record support, YEAAAH, RECOOORD
Change contents
- replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 443
context = Context(up = listOf(3.107), new = IntRange(0, 10), down = emptyList()),context = Context(up = listOf(3.107), new = Range(0, 10), down = emptyList()), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 504
context = Context(up = listOf(0.11), new = IntRange(12, 36), down = emptyList()),context = Context(up = listOf(0.11), new = Range(12, 36), down = emptyList()), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 514
context = Context(up = listOf(3.107), new = IntRange(843, 853), down = emptyList()),context = Context(up = listOf(3.107), new = Range(843, 853), down = emptyList()), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 556
context = Context(up = listOf(0.854), new = IntRange(855, 879), down = emptyList()),context = Context(up = listOf(0.854), new = Range(855, 879), down = emptyList()), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 576
context = Context(up = listOf(3.4473), new = IntRange(1584, 1698), down = listOf(3.4473)),context = Context(up = listOf(3.4473), new = Range(1584, 1698), down = listOf(3.4473)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 599
context = Context(up = listOf(3.6839), new = IntRange(1699, 1950), down = listOf(3.6839)),context = Context(up = listOf(3.6839), new = Range(1699, 1950), down = listOf(3.6839)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 707
context = Context(up = listOf(3.6847), new = IntRange(1951, 1964), down = emptyList()),context = Context(up = listOf(3.6847), new = Range(1951, 1964), down = emptyList()), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 723
context = Context(up = listOf(3.11015), new = IntRange(4000, 4103), down = listOf(3.11015)),context = Context(up = listOf(3.11015), new = Range(4000, 4103), down = listOf(3.11015)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 739
context = Context(up = listOf(3.11075), new = IntRange(4104, 4156), down = listOf(3.11075)),context = Context(up = listOf(3.11075), new = Range(4104, 4156), down = listOf(3.11075)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 755
context = Context(up = listOf(4.2779), new = IntRange(4157, 4222), down = listOf(3.11119)),context = Context(up = listOf(4.2779), new = Range(4157, 4222), down = listOf(3.11119)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 781
context = Context(up = listOf(3.1361), new = IntRange(4223, 4490), down = listOf(3.1361)),context = Context(up = listOf(3.1361), new = Range(4223, 4490), down = listOf(3.1361)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 868
context = Context(up = listOf(3.13611), new = IntRange(4491, 5952), down = listOf(3.13611)),context = Context(up = listOf(3.13611), new = Range(4491, 5952), down = listOf(3.13611)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 884
context = Context(up = listOf(3.24239), new = IntRange(5953, 6018), down = listOf(3.24239)),context = Context(up = listOf(3.24239), new = Range(5953, 6018), down = listOf(3.24239)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 900
context = Context(up = listOf(3.24475), new = IntRange(6019, 6074), down = listOf(3.24475)),context = Context(up = listOf(3.24475), new = Range(6019, 6074), down = listOf(3.24475)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 918
context = Context(up = listOf(3.25153), new = IntRange(6075, 6178), down = listOf(3.25153)),context = Context(up = listOf(3.25153), new = Range(6075, 6178), down = listOf(3.25153)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 928
context = Context(up = listOf(1.0), new = IntRange(6179, 6190), down = emptyList()),context = Context(up = listOf(1.0), new = Range(6179, 6190), down = emptyList()), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 939
context = Context(up = listOf(5.14803), new = IntRange(6193, 6231), down = listOf(5.14803)),context = Context(up = listOf(5.14803), new = Range(6193, 6231), down = listOf(5.14803)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 961
context = Context(up = listOf(5.1482), new = IntRange(6232, 6394), down = listOf(5.1482)),context = Context(up = listOf(5.1482), new = Range(6232, 6394), down = listOf(5.1482)), - replacement in src/test/kotlin/com/github/jonathanxd/dracon/test/DraconTest.kt at line 1012
context = Context(up = listOf(2.59651), new = IntRange(6395, 8239), down = emptyList()),context = Context(up = listOf(2.59651), new = Range(6395, 8239), down = emptyList()), - edit in src/main/resources/META-INF/plugin.xml at line 5
- edit in src/main/resources/META-INF/plugin.xml at line 20
- edit in src/main/resources/META-INF/plugin.xml at line 34
- edit in src/main/resources/META-INF/plugin.xml at line 72
- edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 13
import com.github.jonathanxd.dracon.cache.FileStatusCache - edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 17
import com.intellij.openapi.components.service - edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 23
import com.intellij.vcsUtil.VcsUtilimport java.nio.file.Pathsimport java.time.Durationimport java.time.Instantimport java.util.concurrent.atomic.AtomicReference - edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 30
private val cache = project.service<FileStatusCache>() - replacement in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 34
if (!Pijul.isUnderPijul(virtualFile) || isIdeaRoot(virtualFile))if (!Pijul.isUnderPijul(virtualFile) || isIdeaRoot(virtualFile) || !belongsToProject(virtualFile)) - replacement in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 40
val status = pijul(this.project).fileStatus(this.project, virtualFile)val status = this.cache.load(Paths.get(VcsUtil.getFilePath(virtualFile).path)) - edit in src/main/kotlin/com/github/jonathanxd/dracon/vfs/PijulVirtualFileStatusProvider.kt at line 48
fun belongsToProject(virtualFile: VirtualFile): Boolean =virtualFile.path.startsWith(project.basePath!!) - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/RevisionContentResolver.kt at line 3
import com.github.jonathanxd.dracon.pijul.SuccessStatusCode - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/RevisionContentResolver.kt at line 60
if (rollbackOp.statusCode !is SuccessStatusCode) {throw IllegalStateException("Failed to load state of file $filePath in revision $revisionHash. $rollbackOp")} - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/RevisionContentResolver.kt at line 66
if (resetOp.statusCode !is SuccessStatusCode) {throw IllegalStateException("Failed to load state of file $filePath in revision $revisionHash during reset. $revisions")} - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/RevisionContentResolver.kt at line 71
if (rollbackOp.statusCode !is SuccessStatusCode) {throw IllegalStateException("Failed to load state of file $filePath in revision $revisionHash during unrecord. $rollbackOp")} - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/PijulVcsFileRevision.kt at line 3
import com.github.jonathanxd.dracon.cache.FileRevisionCacheimport com.intellij.openapi.components.service - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/PijulVcsFileRevision.kt at line 38
private val content = this.project.service<FileRevisionCache>().loadAsync(this) - replacement in src/main/kotlin/com/github/jonathanxd/dracon/revision/PijulVcsFileRevision.kt at line 41
override fun loadContent(): ByteArray =loadStateInRevision(this.revision.hash, this.project, vcsRoot, this.filePath).toByteArray(Charsets.UTF_8)override fun loadContent(): ByteArray = this.content.get() - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/PijulRevisionNumber.kt at line 6
import java.io.Serializable - replacement in src/main/kotlin/com/github/jonathanxd/dracon/revision/PijulRevisionNumber.kt at line 10
class PijulRevisionNumber(val hash: String, val timestamp: ZonedDateTime) : ShortVcsRevisionNumber {class PijulRevisionNumber(val hash: String, val timestamp: ZonedDateTime) : ShortVcsRevisionNumber, Serializable { - edit in src/main/kotlin/com/github/jonathanxd/dracon/revision/PijulRevisionNumber.kt at line 27
companion object {private const val serialVersionUID: Long = 1} - edit in src/main/kotlin/com/github/jonathanxd/dracon/provider/PijulChangeProvider.kt at line 3
import com.github.jonathanxd.dracon.cache.PijulLogEntryChangeCache - edit in src/main/kotlin/com/github/jonathanxd/dracon/provider/PijulChangeProvider.kt at line 8
import com.intellij.openapi.components.service - edit in src/main/kotlin/com/github/jonathanxd/dracon/provider/PijulChangeProvider.kt at line 21
private val logEntryChangeCache = project.service<PijulLogEntryChangeCache>() - replacement in src/main/kotlin/com/github/jonathanxd/dracon/provider/PijulChangeProvider.kt at line 52
val rootPath = Paths.get(root!!.path)val head = revisionMap.computeIfAbsent(rootPath) {pijul(this.project).latestRevisionNumber(this.project, root).result} ?: continueval rootPath = Paths.get(root.path) - replacement in src/main/kotlin/com/github/jonathanxd/dracon/provider/PijulChangeProvider.kt at line 54
val change = changesMap.computeIfAbsent(rootPath) {pijul(this.project).diff(this.project, root).result} ?: continueval head = this.logEntryChangeCache.loadRevision(rootAbsolute) {pijul(this.project).latestRevisionNumber(this.project, rootPath)}.result ?: continue - edit in src/main/kotlin/com/github/jonathanxd/dracon/provider/PijulChangeProvider.kt at line 58
val change = this.logEntryChangeCache.load(rootAbsolute) {pijul(this.project).diff(this.project, root)}.result ?: continue - file addition: PijulFilesStatus.kt[3.3420]
package com.github.jonathanxd.dracon.pijulimport com.intellij.openapi.vcs.FileStatusimport java.nio.file.Pathdata class PijulFilesStatus(val changed: Map<Path, List<FileStatus>>,val tracked: List<Path>) - edit in src/main/kotlin/com/github/jonathanxd/dracon/pijul/Pijul.kt at line 83
@RequiresBackgroundThreadfun fileStatus(project: Project, file: Path): PijulOperationResult<FileStatus> - edit in src/main/kotlin/com/github/jonathanxd/dracon/pijul/Pijul.kt at line 88
fun fileStatusMap(project: Project): PijulOperationResult<PijulFilesStatus>@RequiresBackgroundThread - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 14
data class Author(val name: String?, val fullName: String?, val email: String?): Serializabledata class Author(val name: String?, val fullName: String?, val email: String?): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 29
): Serializable): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 43
): Serializable): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 56
private const val serialVersionUID: Long = 1L - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 64
data class IndexInt(val index: Int) : IntOrAsterisk(), Serializabledata class IndexInt(val index: Int) : IntOrAsterisk(), Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 89
UNKNOWNUNKNOWN;companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 126
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 144
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 163
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 180
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 199
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 218
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 236
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 255
companion object {private const val serialVersionUID: Long = 1L} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 274
companion object {private const val serialVersionUID: Long = 1L} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 285
data class Meta(val plain: String): Serializabledata class Meta(val plain: String): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 296
data class Flag(val plain: String): Serializabledata class Flag(val plain: String): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 306
): Serializable): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 312
data class Range(val start: Int, val end: Int): Serializabledata class Range(val start: Int, val end: Int): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 337
ZOMBIE_RESURRECTZOMBIE_RESURRECT;companion object {private const val serialVersionUID: Long = 1L} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 344
data class LineChange(val type: LineChangeType, val data: String): Serializabledata class LineChange(val type: LineChangeType, val data: String): Serializable {companion object {private const val serialVersionUID: Long = 1L}} - edit in src/main/kotlin/com/github/jonathanxd/dracon/log/PijulLog.kt at line 358
private const val serialVersionUID: Long = 1L - file addition: listeners[3.107]
- file addition: PijulAsyncFileListener.kt[0.7108]
package com.github.jonathanxd.dracon.listenersimport com.github.jonathanxd.dracon.cache.FileStatusCacheimport com.github.jonathanxd.dracon.cache.PijulLogEntryChangeCacheimport com.intellij.openapi.components.serviceimport com.intellij.openapi.externalSystem.autoimport.AsyncFileChangeListenerBaseimport com.intellij.openapi.project.Projectimport com.intellij.openapi.roots.ProjectRootManagerimport com.intellij.openapi.vfs.AsyncFileListenerimport com.intellij.openapi.vfs.VirtualFileimport com.intellij.openapi.vfs.newvfs.events.VFileEventimport com.intellij.vcsUtil.VcsUtilimport java.nio.file.Pathsimport java.util.concurrent.CopyOnWriteArrayListclass PijulAsyncFileListener(val project: Project) : AsyncFileChangeListenerBase(), AsyncFileListener {private val fileStatusCache by lazy { this.project.service<FileStatusCache>() }private val pijulLogEntryChangeCache by lazy { this.project.service<PijulLogEntryChangeCache>() }override fun apply() {}override fun init() {}override fun isRelevant(file: VirtualFile, event: VFileEvent): Boolean {return ProjectRootManager.getInstance(this.project).fileIndex.isInContent(file)}override fun updateFile(file: VirtualFile, event: VFileEvent) {if (ProjectRootManager.getInstance(this.project).fileIndex.isInContent(file)) {this.fileStatusCache.unload(Paths.get(VcsUtil.getFilePath(file).path))this.pijulLogEntryChangeCache.unload(Paths.get(VcsUtil.getFilePath(file).path))}}} - edit in src/main/kotlin/com/github/jonathanxd/dracon/context/PijulVcsContext.kt at line 4
import com.github.jonathanxd.dracon.listeners.PijulAsyncFileListener - edit in src/main/kotlin/com/github/jonathanxd/dracon/context/PijulVcsContext.kt at line 6
import com.intellij.openapi.Disposable - edit in src/main/kotlin/com/github/jonathanxd/dracon/context/PijulVcsContext.kt at line 13
import com.intellij.openapi.vfs.VirtualFileManager - replacement in src/main/kotlin/com/github/jonathanxd/dracon/context/PijulVcsContext.kt at line 20
class PijulVcsContext(val project: Project) {val root by lazy {class PijulVcsContext(val project: Project): Disposable {init {VirtualFileManager.getInstance().addAsyncFileListener(PijulAsyncFileListener(project),this)}override fun dispose() {}val root: Path get() { - replacement in src/main/kotlin/com/github/jonathanxd/dracon/context/PijulVcsContext.kt at line 35
ProjectLevelVcsManager.getInstance(this.project).getRootsUnderVcs(pijulVcs(this.project)).first().toNioPath()return ProjectLevelVcsManager.getInstance(this.project).getRootsUnderVcs(pijulVcs(this.project)).firstOrNull()?.toNioPath() ?: Paths.get(project.basePath!!) - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 13
import com.github.jonathanxd.dracon.cache.HashKey - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 16
import com.github.jonathanxd.dracon.cache.persist.DraconPersistentStateComponent - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 44[3.11786]→[3.11786:11819](∅→∅),[3.11819]→[3.15173:15256](∅→∅),[3.15256]→[3.11819:11877](∅→∅),[3.11819]→[3.11819:11877](∅→∅),[3.11877]→[3.8268:8297](∅→∅)
import kotlinx.coroutines.flow.*import kotlinx.coroutines.future.asDeferredimport kotlinx.coroutines.future.awaitimport kotlinx.coroutines.runBlockingimport java.io.Fileimport java.net.ServerSocket - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 123
val fileStatusBasedInPijulLs = this.doExecutionWithMapper("file_status_from_ls", this.createExecPijulOperation(project, rootPath, listOf("ls"), delay = 10L)) {val fileStatusBasedInPijulLs =this.doExecutionWithMapper("file_status_from_ls", this.createExecPijulOperation(project, rootPath, listOf("ls"), log = false)) { - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 141
}}@OptIn(ExperimentalPathApi::class)@RequiresBackgroundThreadoverride fun fileStatus(project: Project, file: Path): PijulOperationResult<FileStatus> {val root = project.service<PijulVcsContext>().rootval execution = this.createPainlessExecPijulOperation(project, root, listOf("diff", "--json"))val fileStatusBasedInPijulDiff = this.doExecutionWithMapper("file_status", execution) {try {val changes = PijulDiffJson.parseJson(it)val changeMap = changes.toFileStatusMap()val fPath = file.relativeTo(root).toString()if (fPath.isEmpty()) {FileStatus.SUPPRESSED} else {changeMap[fPath]?.firstOrNull()}} catch(t: Throwable) {logger<PijulCmd>().error(t)null}}val fileStatusBasedInPijulLs =this.doExecutionWithMapper("file_status_from_ls", this.createExecPijulOperation(project, root, listOf("ls"), log = false)) {val trackedFiles = it.split("\n")val fPath = file.relativeTo(root).toString()if (trackedFiles.contains(fPath)) {FileStatus.NOT_CHANGED} else {FileStatus.UNKNOWN}}return if (fileStatusBasedInPijulDiff.statusCode !is SuccessStatusCode|| fileStatusBasedInPijulDiff.result == null|| fileStatusBasedInPijulDiff.result == FileStatus.SUPPRESSED) {fileStatusBasedInPijulLs} else {fileStatusBasedInPijulDiff}}override fun fileStatusMap(project: Project): PijulOperationResult<PijulFilesStatus> {val root = project.service<PijulVcsContext>().rootval fileStatusMap = mutableMapOf<Path, List<FileStatus>>()val tracked = mutableListOf<Path>()val execution = this.createPainlessExecPijulOperation(project, root, listOf("diff", "--json"))val fileStatusBasedInPijulDiff = this.doExecutionWithMapper("file_status", execution) {try {val changes = PijulDiffJson.parseJson(it)val changeMap = changes.toFileStatusMap()for (c in changeMap) {fileStatusMap[root.resolve(c.key)] = c.value}} catch(t: Throwable) {logger<PijulCmd>().error(t)null}}val fileStatusBasedInPijulLs =this.doExecutionWithMapper("file_status_from_ls", this.createExecPijulOperation(project, root, listOf("ls"), log = false)) {it.split("\n").mapTo(tracked) {root.resolve(it)}}if (fileStatusBasedInPijulDiff.statusCode !is SuccessStatusCode) {return fileStatusBasedInPijulDiff as PijulOperationResult<PijulFilesStatus> - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 219
if (fileStatusBasedInPijulLs.statusCode !is SuccessStatusCode) {return fileStatusBasedInPijulLs as PijulOperationResult<PijulFilesStatus>}return PijulOperationResult("file_status", SuccessStatusCode, PijulFilesStatus(fileStatusMap, tracked)) - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 246
for (rollbackHash in rollbacks) {if (rollbackHash == hash)break; - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 247[3.16060]→[3.10190:10301](∅→∅),[3.10190]→[3.10190:10301](∅→∅),[3.10301]→[3.16061:16187](∅→∅),[3.16187]→[3.10406:10608](∅→∅),[3.10406]→[3.10406:10608](∅→∅)
val rollback = this.doExecution("rollback_$rollbackHash",this.createPainlessExecPijulOperation(project, root, listOf("unrecord", "--reset", rollbackHash)))if (rollback.statusCode !is SuccessStatusCode) {return rollback as PijulOperationResult<Boolean>}val rollback = this.doExecution("rollback_from_${hashList[0]}_until_$hash",this.createPainlessExecPijulOperation(project, root, listOf("unrecord", "--reset") + rollbacks)) - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 252
this.reset(project, root)if (rollback.statusCode !is SuccessStatusCode) {return rollback as PijulOperationResult<Boolean> - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 355
val resetExecution = this.createExecPijulOperation(project, root, listOf("reset"), delay = 10L)val resetExecution = this.createExecPijulOperation(project, root, listOf("reset")) - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 414
val change = this.pijulLogEntryCache.queryOrCompute(hash) {val change = this.pijulLogEntryCache.load(hash) { - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 480
val change = this.pijulLogEntryCache.queryOrCompute(hash) {val change = this.pijulLogEntryCache.load(hash) { - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 540
val change = this.doExecutionWithMapper("diff", this.createExecPijulOperation(project, rootPath, listOf("diff"), delay = 10L)) {val change = this.doExecutionWithMapper("diff", this.createExecPijulOperation(project, rootPath, listOf("diff"))) { - edit in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 674
@Deprecated(message = "Deprecated in favor of createPainlessExecPijulOperation, which does not require a delay parameter to be provided!") - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 678
delay: Long = 1000L): PijulExecution {log: Boolean = true): PijulExecution { - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 687
input.split("\n").forEach {draconConsoleWriter(project).logCommand("pijul", args, it)if (log) {input.split("\n").forEach {draconConsoleWriter(project).logCommand("pijul", args, it)} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cmd/PijulCmd.kt at line 693
error.split("\n").forEach {draconConsoleWriter(project).logCommandError("pijul", args, it)if (log) {error.split("\n").forEach {draconConsoleWriter(project).logCommandError("pijul", args, it)} - replacement in src/main/kotlin/com/github/jonathanxd/dracon/changes/PijulCommittedChangesProvider.kt at line 129
entry.hunks.filterIsInstance<HunkWithPath>().map { hunk ->entry.hunks.filterIsInstance<HunkWithPath>().groupBy { it.resolvePath(ctx.root) }.map { (p, hunks) ->val hunk = hunks.firstOrNull { it is EditHunk }?: hunks.firstOrNull { it is ReplacementHunk }?: hunks.firstOrNull { it is FileDelHunk }?: hunks.firstOrNull { it is FileAddHunk }?: hunks.first() - file move: cache → cache
- file move: persist → persist
- file addition: PijulLogEntryChangeCache.kt[2.8571]
package com.github.jonathanxd.dracon.cacheimport com.github.jonathanxd.dracon.context.PijulVcsContextimport com.github.jonathanxd.dracon.log.PijulLogEntryimport com.github.jonathanxd.dracon.pijul.PijulOperationResultimport com.github.jonathanxd.dracon.pijul.SuccessStatusCodeimport com.github.jonathanxd.dracon.revision.PijulRevisionNumberimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport java.nio.file.Pathimport kotlin.io.path.ExperimentalPathApiimport kotlin.io.path.relativeTo@Suppress("UnstableApiUsage")@OptIn(ExperimentalPathApi::class)@Serviceclass PijulLogEntryChangeCache(val project: Project) {private val dataCache = DataCache<String, PijulLogEntry>(project, "path_change")private val revisionDataCache = DataCache<String, PijulRevisionNumber>(project, "revision")fun load(path: Path, compute: () -> PijulOperationResult<PijulLogEntry>): PijulOperationResult<PijulLogEntry> {val ctx = this.project.service<PijulVcsContext>()val relativePath = path.relativeTo(ctx.root).toString()return this.dataCache.queryOrLoad(relativePath,{ compute() },{ it.statusCode is SuccessStatusCode && it.result != null },{it.result!!},{ PijulOperationResult("file_changes", SuccessStatusCode, it) })}fun loadRevision(path: Path, compute: () -> PijulOperationResult<PijulRevisionNumber>): PijulOperationResult<PijulRevisionNumber> {val ctx = this.project.service<PijulVcsContext>()val relativePath = path.relativeTo(ctx.root).toString()return this.revisionDataCache.queryOrLoad(relativePath,{ compute() },{ it.statusCode is SuccessStatusCode },{it.result!!},{ PijulOperationResult("revision", SuccessStatusCode, it) })}fun unload(path: Path) {val ctx = this.project.service<PijulVcsContext>()val relativePath = path.relativeTo(ctx.root).toString()this.dataCache.unload(relativePath)this.dataCache.unload("")this.revisionDataCache.unload(relativePath)this.revisionDataCache.unload("")}} - edit in src/main/kotlin/com/github/jonathanxd/dracon/cache/PijulLogEntryCache.kt at line 3
import com.github.jonathanxd.dracon.cache.persist.createLogEntriesPersistimport com.github.jonathanxd.dracon.cache.persist.toPijulLogEntriesMap - edit in src/main/kotlin/com/github/jonathanxd/dracon/cache/PijulLogEntryCache.kt at line 7
import com.intellij.openapi.project.getProjectDataPathimport java.nio.file.Filesimport java.util.concurrent.ConcurrentHashMap - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cache/PijulLogEntryCache.kt at line 10
private val map = ConcurrentHashMap<String, PijulLogEntry>()private val cachePath = project.getProjectDataPath("com.jonathanxd.dracon")private val cacheFile = cachePath.resolve("log.obj")private val dataCache = DataCache<String, PijulLogEntry>(project, "change") - replacement in src/main/kotlin/com/github/jonathanxd/dracon/cache/PijulLogEntryCache.kt at line 12
init {Files.createDirectories(cachePath)if (Files.exists(this.cacheFile)) {try {this.map.putAll(this.cacheFile.toPijulLogEntriesMap())} catch (e: Throwable) {Files.delete(this.cacheFile)}}}fun queryOrCompute(hash: String, compute: () -> PijulOperationResult<PijulLogEntry>): PijulOperationResult<PijulLogEntry> {return if (!this.map.containsKey(hash)) {val computeEntry = compute()if (computeEntry.statusCode !is SuccessStatusCode) {return computeEntry}this.map[hash] = computeEntry.result!!this.cacheFile.createLogEntriesPersist(this.map)computeEntry} else {PijulOperationResult("change-$hash", SuccessStatusCode, this.map[hash])}fun load(hash: String, compute: () -> PijulOperationResult<PijulLogEntry>): PijulOperationResult<PijulLogEntry> {return this.dataCache.queryOrLoad(hash,{ compute() },{ it.statusCode is SuccessStatusCode },{it.result!!},{ PijulOperationResult("change-$hash", SuccessStatusCode, it) }) - file addition: FileStatusCache.kt[2.8571]
package com.github.jonathanxd.dracon.cacheimport com.github.jonathanxd.dracon.context.PijulVcsContextimport com.github.jonathanxd.dracon.pijul.PijulOperationResultimport com.github.jonathanxd.dracon.pijul.SuccessStatusCodeimport com.github.jonathanxd.dracon.pijul.pijulimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport com.intellij.openapi.vcs.FileStatusimport com.intellij.openapi.vcs.FileStatusFactoryimport java.io.Serializableimport java.nio.file.Pathimport kotlin.io.path.ExperimentalPathApiimport kotlin.io.path.relativeTo@OptIn(ExperimentalPathApi::class)@Serviceclass FileStatusCache(val project: Project) {private val cache = DataCache<String, CacheablePijulFileStatus>(this.project, "file_status")init {// Pre-load statusthis.cache.lock()try {val ctx = this.project.service<PijulVcsContext>()val map = pijul(project).fileStatusMap(project)if (map.result != null) {for (change in map.result.changed) {if (change.value.isNotEmpty()) {val path = change.key.relativeTo(ctx.root)this.cache.queryOrLoad(path.toString()) {change.value.first().toPijul()}}}for (tracked in map.result.tracked) {val path = tracked.relativeTo(ctx.root)this.cache.queryOrLoad(path.toString()) {FileStatus.NOT_CHANGED.toPijul()}}}} finally {this.cache.unlock()}}fun load(path: Path): PijulOperationResult<FileStatus> {val ctx = this.project.service<PijulVcsContext>()return this.cache.queryOrLoad(path.relativeTo(ctx.root).toString(),{ pijul(project).fileStatus(project, path) },{ it.statusCode is SuccessStatusCode },{ it.result!!.toPijul() },{ PijulOperationResult("file_status", SuccessStatusCode, it.toFileStatus()) })}fun unload(path: Path) {val ctx = this.project.service<PijulVcsContext>()val relativePath = path.relativeTo(ctx.root).toString()this.cache.unload(relativePath)}}data class CacheablePijulFileStatus(val id: String) : Serializable {companion object {private const val serialVersionUID: Long = 1}}fun FileStatus.toPijul(): CacheablePijulFileStatus = CacheablePijulFileStatus(this.id)fun CacheablePijulFileStatus.toFileStatus(): FileStatus =try {FileStatus::class.java.getDeclaredField(this.id).get(null) as FileStatus} catch (t: Throwable) {FileStatusFactory.getInstance().allFileStatuses.first {it.id == this.id}} - file addition: FileRevisionCache.kt[2.8571]
package com.github.jonathanxd.dracon.cacheimport com.github.jonathanxd.dracon.context.PijulVcsContextimport com.github.jonathanxd.dracon.revision.PijulVcsFileRevisionimport com.github.jonathanxd.dracon.revision.loadStateInRevisionimport com.intellij.openapi.components.Serviceimport com.intellij.openapi.components.serviceimport com.intellij.openapi.project.Projectimport java.io.Serializableimport java.util.concurrent.CompletableFutureimport java.util.concurrent.Executorsimport java.util.concurrent.locks.ReentrantLock@Serviceclass FileRevisionCache(val project: Project) {private val cache = DataCache<FileRevisionRef, ByteArray>(this.project, "file_revision")fun loadAsync(rev: PijulVcsFileRevision): CompletableFuture<ByteArray> {val root = project.service<PijulVcsContext>().rootval fileRev = FileRevisionRef(rev.filePath.toAbsolutePath().toString(), rev.revision.hash)return this.cache.queryOrLoadAsync(fileRev) {loadStateInRevision(rev.revision.hash,this.project,root,rev.filePath).toByteArray(Charsets.UTF_8)}}}data class FileRevisionRef(val filePath: String,val revision: String): Serializable - file addition: DataCache.kt[2.8571]
package com.github.jonathanxd.dracon.cacheimport com.intellij.openapi.project.Projectimport com.intellij.openapi.project.getProjectDataPathimport java.io.ObjectInputStreamimport java.io.ObjectOutputStreamimport java.nio.file.Filesimport java.nio.file.Pathimport java.nio.file.StandardOpenOptionimport java.util.concurrent.CompletableFutureimport java.util.concurrent.ConcurrentHashMapimport java.util.concurrent.Executorsimport java.util.concurrent.locks.ReentrantLockimport java.util.zip.GZIPInputStreamimport java.util.zip.GZIPOutputStream@Suppress("UnstableApiUsage")class DataCache<K, V>(val project: Project,val name: String) {private val cachePath = project.getProjectDataPath("com.github.jonathanxd.dracon")private val cacheFile = cachePath.resolve("$name.gz")private val manager = DataCacheManager<K, V>(this.cacheFile)private val lock = ReentrantLock()private val updateExecutor = Executors.newCachedThreadPool()private val inMemory = ConcurrentHashMap<K, V>()init {this.manager.load()?.let {this.inMemory.putAll(it)}}fun lock() {this.lock.lock()}fun unlock() {this.lock.unlock()}fun unload(key: K) {this.lock.lock()try {this.inMemory.remove(key)this.manager.write(this.inMemory)} finally {this.lock.unlock()}}fun queryOrLoad(key: K, compute: (K) -> V): V {this.lock.lock()try {return if (!this.inMemory.containsKey(key)) {val computeEntry = compute(key)this.inMemory[key] = computeEntrythis.manager.write(this.inMemory)computeEntry} else {this.inMemory[key]!!}} finally {this.lock.unlock();}}fun <I> queryOrLoad(key: K,compute: (K) -> I,filter: (I) -> Boolean,iMapper: (I) -> V,vMapper: (V) -> I): I {this.lock.lock()try {return if (!this.inMemory.containsKey(key)) {val computeEntry = compute(key)if (!filter(computeEntry)) {return computeEntry}this.inMemory[key] = iMapper(computeEntry!!)this.manager.write(this.inMemory)computeEntry} else {vMapper(this.inMemory[key]!!)}} finally {this.lock.unlock();}}fun queryOrLoadAsync(key: K, compute: (K) -> V): CompletableFuture<V> {if (this.inMemory.containsKey(key)) {return CompletableFuture.completedFuture(this.inMemory[key]!!)} else {return CompletableFuture.supplyAsync({this.lock.lock()try {val computeEntry = compute(key)this.inMemory[key] = computeEntrythis.manager.write(this.inMemory)computeEntry} finally {this.lock.unlock()}}, this.updateExecutor)}}fun <I> queryOrLoadAsync(key: K,compute: (K) -> I,filter: (I) -> Boolean,iMapper: (I) -> V,vMapper: (V) -> I): CompletableFuture<I> {if (this.inMemory.containsKey(key)) {return CompletableFuture.completedFuture(vMapper(this.inMemory[key]!!))} else {return CompletableFuture.supplyAsync({this.lock.lock()try {val computeEntry = compute(key)if (!filter(computeEntry)) {computeEntry} else {this.inMemory[key] = iMapper(computeEntry!!)this.manager.write(this.inMemory)computeEntry}} finally {this.lock.unlock()}}, this.updateExecutor)}}}class DataCacheManager<K, V>(val path: Path) {init {Files.createDirectories(this.path.parent)}fun load(): Map<K, V>? {if (!Files.exists(this.path)) return nulltry {Files.newInputStream(this.path).use { stream ->GZIPInputStream(stream).use { gz ->ObjectInputStream(gz).use { reader ->return reader.readObject() as Map<K, V>}}}} catch (t: Throwable) {t.printStackTrace()Files.delete(this.path)return null}}fun write(data: Map<K, V>) {Files.newOutputStream(this.path, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING).use { writer ->GZIPOutputStream(writer).use { compress ->ObjectOutputStream(compress).use { oos ->oos.writeObject(data)}}}}} - edit in src/main/kotlin/com/github/jonathanxd/dracon/PijulVcs.kt at line 16
import com.github.jonathanxd.dracon.listeners.PijulAsyncFileListener - edit in src/main/kotlin/com/github/jonathanxd/dracon/PijulVcs.kt at line 20
import com.intellij.openapi.Disposable - edit in src/main/kotlin/com/github/jonathanxd/dracon/PijulVcs.kt at line 32
import com.intellij.openapi.vcs.history.VcsRevisionNumber - edit in src/main/kotlin/com/github/jonathanxd/dracon/PijulVcs.kt at line 34
import com.intellij.openapi.vfs.VirtualFileManager - edit in src/main/kotlin/com/github/jonathanxd/dracon/PijulVcs.kt at line 48
override fun activate() {super.activate()}