Skip to content

Commit

Permalink
Merge pull request #525 from handymenny/index-immutable-cache
Browse files Browse the repository at this point in the history
index: cache LibraryIndexImmutable
  • Loading branch information
handymenny authored Nov 4, 2024
2 parents a1fc79e + 9e2f01f commit ce3489b
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,34 +23,45 @@ import kotlinx.coroutines.withContext
import kotlinx.serialization.Required
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json

@Serializable
@SerialName("LibraryIndex")
data class LibraryIndexImmutable(
@Required val items: List<IndexLine>,
val multiItems: List<MultiIndexLine> = emptyList(),
)
) {
val jsonString by lazy { Json.custom().encodeToString(this) }
}

class LibraryIndex(outputCacheSize: Int?) {
private val items: MutableMap<String, IndexLine> = mutableMapOf()
private val multiItems: MutableMap<String, MultiIndexLine> = mutableMapOf()
private val outputCache = LruCache<String, Capabilities>(outputCacheSize)
private var cachedImmutable: LibraryIndexImmutable? = null
private val lock = Any()

fun addLine(line: IndexLine) {
synchronized(lock) { items[line.id] = line }
synchronized(lock) {
items[line.id] = line
cachedImmutable = null
}
}

fun replaceLine(line: IndexLine) {
synchronized(lock) {
items[line.id] = line
outputCache.remove(line.id)
cachedImmutable = null
}
}

fun addMultiLine(line: MultiIndexLine) {
synchronized(lock) { multiItems[line.id] = line }
synchronized(lock) {
multiItems[line.id] = line
cachedImmutable = null
}
}

fun find(id: String): IndexLine? = items[id]
Expand Down Expand Up @@ -104,19 +115,24 @@ class LibraryIndex(outputCacheSize: Int?) {
}

fun toImmutableIndex(): LibraryIndexImmutable {
val itemsArray: Array<IndexLine>
val multiItemsArray: Array<MultiIndexLine>
// check if we've a cached valid value
cachedImmutable?.let {
return it
}

synchronized(lock) {
itemsArray = items.values.toTypedArray()
multiItemsArray = multiItems.values.toTypedArray()
}
val items = items.values.toTypedArray()
val multiItems = multiItems.values.toTypedArray()

// stable sorting
itemsArray.sortWith(compareBy<IndexLine>({ it.timestamp }, { it.id }).reversed())
multiItemsArray.sortWith(compareBy<MultiIndexLine>({ it.timestamp }, { it.id }).reversed())
// stable sorting
items.sortWith(compareBy<IndexLine>({ it.timestamp }, { it.id }).reversed())
multiItems.sortWith(compareBy<MultiIndexLine>({ it.timestamp }, { it.id }).reversed())

return LibraryIndexImmutable(itemsArray.toList(), multiItemsArray.toList())
val newImmutableIndex = LibraryIndexImmutable(items.toList(), multiItems.toList())
cachedImmutable = newImmutableIndex

return newImmutableIndex
}
}

suspend fun populateIndexAsync(path: String) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ object Routes {
}

fun storeList(ctx: Context, index: LibraryIndex) {
ctx.json(index.toImmutableIndex())
ctx.contentType("application/json")
ctx.result(index.toImmutableIndex().jsonString)
}

fun storeGetItem(ctx: Context, index: LibraryIndex) {
Expand Down

0 comments on commit ce3489b

Please sign in to comment.