mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
IJPL-171417 Go to target (choose implementation) freezes if there are many results
- Optimized replaceAll method: the cache is not reset unnecessarily GitOrigin-RevId: a7d1bbc5763463eea039b8dee52d8ad025bfcdb8
This commit is contained in:
committed by
intellij-monorepo-bot
parent
a60b64fe8a
commit
daf3404311
@@ -16,6 +16,8 @@ import javax.swing.event.ListDataListener
|
||||
@TestOnly
|
||||
class WideSelectionListCache(private val list: JList<*>) {
|
||||
|
||||
private var modelChanged = false
|
||||
|
||||
/**
|
||||
* Key is a value from the [list].
|
||||
* Don't cache `null` value because of using [MutableMap.getOrPut]
|
||||
@@ -25,21 +27,27 @@ class WideSelectionListCache(private val list: JList<*>) {
|
||||
val preferredSizeCache: MutableMap<Any, Dimension> = IdentityHashMap()
|
||||
|
||||
private val listDataListener = object : ListDataListener {
|
||||
override fun intervalAdded(e: ListDataEvent?) {}
|
||||
override fun intervalAdded(e: ListDataEvent?) {
|
||||
// No need modelChanged, the cache will be filled later when needed
|
||||
purgeIfNeeded()
|
||||
}
|
||||
|
||||
override fun intervalRemoved(e: ListDataEvent) {
|
||||
purge()
|
||||
modelChanged = true
|
||||
// No need purgeIfNeeded, because `replaceAll` method does `removeAllItems` and `addAllItems`,
|
||||
// which leads to unnecessary full cache rebuilding.
|
||||
}
|
||||
|
||||
override fun contentsChanged(e: ListDataEvent) {
|
||||
purge()
|
||||
modelChanged = true
|
||||
purgeIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
private val modelChangeListener = PropertyChangeListener { evt ->
|
||||
uninstallListDataListener(evt.oldValue as ListModel<*>?)
|
||||
installListDataListener(evt.newValue as ListModel<*>?)
|
||||
preferredSizeCache.clear()
|
||||
clear()
|
||||
}
|
||||
|
||||
fun installListeners() {
|
||||
@@ -50,17 +58,35 @@ class WideSelectionListCache(private val list: JList<*>) {
|
||||
fun uninstallListeners() {
|
||||
list.removePropertyChangeListener("model", modelChangeListener)
|
||||
uninstallListDataListener(list.model)
|
||||
preferredSizeCache.clear()
|
||||
clear()
|
||||
}
|
||||
|
||||
fun getCachedPreferredSizeOrCalculate(value: Any?, useCache: Boolean, supplier: () -> Dimension): Dimension {
|
||||
if (!useCache || value == null) {
|
||||
if (!useCache) {
|
||||
clear()
|
||||
return supplier()
|
||||
}
|
||||
|
||||
purgeIfNeeded()
|
||||
|
||||
if (value == null) {
|
||||
return supplier()
|
||||
}
|
||||
|
||||
return preferredSizeCache.getOrPut(value, supplier)
|
||||
}
|
||||
|
||||
private fun purge() {
|
||||
private fun clear() {
|
||||
modelChanged = false
|
||||
preferredSizeCache.clear()
|
||||
}
|
||||
|
||||
private fun purgeIfNeeded() {
|
||||
if (!modelChanged) {
|
||||
return
|
||||
}
|
||||
|
||||
modelChanged = false
|
||||
val model = list.model.originalModel
|
||||
|
||||
if (model == null) {
|
||||
|
||||
+2
@@ -57,7 +57,9 @@ class WideSelectionListCacheTest {
|
||||
updateAndCheckCache(list, (0..100).toSet())
|
||||
|
||||
filteringModel.setFilter(null)
|
||||
defaultModel.remove(49)
|
||||
defaultModel.remove(50)
|
||||
defaultModel.addElement(49) // remove doesn't purge the cache
|
||||
val no50 = defaultModel.allItems
|
||||
assertEquals(no50, list.cachedItems)
|
||||
defaultModel.addElement(999)
|
||||
|
||||
Reference in New Issue
Block a user