-
Notifications
You must be signed in to change notification settings - Fork 113
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JT-78303: Refactor persistent cache components; Add tests;
- Loading branch information
1 parent
3031050
commit f100dc6
Showing
11 changed files
with
241 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
43 changes: 43 additions & 0 deletions
43
utils/src/main/kotlin/jetbrains/exodus/core/cache/persistent/VersionTracker.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package jetbrains.exodus.core.cache.persistent | ||
|
||
import java.util.concurrent.ConcurrentHashMap | ||
import java.util.concurrent.atomic.AtomicLong | ||
|
||
// Thread-safe class for tracking current version and clients registered for different versions | ||
internal class VersionTracker(initialVersion: Long = 0) { | ||
|
||
@JvmRecord | ||
internal data class ClientVersion(val client: PersistentCacheClient, val version: Long) | ||
|
||
private val versionRef = AtomicLong(initialVersion) | ||
|
||
private val registeredClients = ConcurrentHashMap.newKeySet<ClientVersion>() | ||
private val versionClientCount = ConcurrentHashMap<Long, Long>() | ||
|
||
fun nextVersion(): Long { | ||
return versionRef.incrementAndGet() | ||
} | ||
|
||
fun register(client: PersistentCacheClient, version: Long) { | ||
val wasAdded = registeredClients.add(ClientVersion(client, version)) | ||
if (wasAdded) { | ||
versionClientCount.compute(version) { _, count -> if (count == null) 1 else count + 1 } | ||
} | ||
} | ||
|
||
fun unregister(client: PersistentCacheClient, version: Long): Long { | ||
val wasRemoved = registeredClients.remove(ClientVersion(client, version)) | ||
val clientsLeft = if (wasRemoved) { | ||
versionClientCount.compute(version) { _, count -> | ||
if (count == null || (count - 1) == 0L) null else count - 1 | ||
} | ||
} else { | ||
versionClientCount[version] | ||
} | ||
return clientsLeft ?: 0 | ||
} | ||
|
||
fun hasNoClients(version: Version): Boolean { | ||
return !versionClientCount.containsKey(version) | ||
} | ||
} |
43 changes: 43 additions & 0 deletions
43
utils/src/main/kotlin/jetbrains/exodus/core/cache/persistent/WeightedValueMap.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package jetbrains.exodus.core.cache.persistent | ||
|
||
import java.util.concurrent.ConcurrentHashMap | ||
import java.util.concurrent.atomic.AtomicInteger | ||
|
||
typealias ValueWeigher<V> = (V) -> Int | ||
|
||
// Thread-safe container for versioned cache entry value that holds total weight of all values collectively | ||
internal class WeightedValueMap<K, V>(private val weigher: ValueWeigher<V>) { | ||
|
||
private val map = ConcurrentHashMap<K, V>() | ||
|
||
// Total weight of all values collectively | ||
private val totalWeightRef = AtomicInteger() | ||
|
||
val size get() = map.size | ||
val keys get() = map.keys | ||
val totalWeight get() = totalWeightRef.get() | ||
|
||
fun put(key: K, value: V) { | ||
map.compute(key) { _, prevValue -> | ||
val toSubtract = prevValue?.let(weigher) ?: 0 | ||
// Coersing is needed to avoid negative values as weigher can return different values for the same value | ||
totalWeightRef.updateAndGet { (it + weigher(value) - toSubtract).coerceAtLeast(0) } | ||
value | ||
} | ||
} | ||
|
||
fun remove(key: K) { | ||
map.computeIfPresent(key) { _, value -> | ||
totalWeightRef.updateAndGet { (it - weigher(value)).coerceAtLeast(0) } | ||
null | ||
} | ||
} | ||
|
||
fun get(key: K): V? { | ||
return map[key] | ||
} | ||
|
||
fun orNullIfEmpty(): WeightedValueMap<K, V>? { | ||
return if (map.isEmpty()) null else this | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.