1
1
package net.corda.node.utilities
2
2
3
3
import com.github.benmanes.caffeine.cache.LoadingCache
4
- import com.github.benmanes.caffeine.cache.Weigher
5
4
import net.corda.core.crypto.SecureHash
6
5
import net.corda.core.internal.NamedCacheFactory
7
6
import net.corda.core.utilities.contextLogger
@@ -10,7 +9,6 @@ import net.corda.nodeapi.internal.persistence.contextTransaction
10
9
import net.corda.nodeapi.internal.persistence.currentDBSession
11
10
import org.hibernate.Session
12
11
import org.hibernate.internal.SessionImpl
13
- import java.util.*
14
12
import java.util.concurrent.ConcurrentHashMap
15
13
import java.util.concurrent.atomic.AtomicBoolean
16
14
import java.util.concurrent.atomic.AtomicReference
@@ -22,7 +20,8 @@ import java.util.stream.Stream
22
20
*
23
21
* This class relies heavily on the fact that compute operations in the cache are atomic for a particular key.
24
22
*/
25
- abstract class AppendOnlyPersistentMapBase <K , V , E , out EK >(
23
+ @Suppress(" TooManyFunctions" )
24
+ abstract class AppendOnlyPersistentMapBase <K : Any , V , E , out EK >(
26
25
val toPersistentEntityKey : (K ) -> EK ,
27
26
val fromPersistentEntity : (E ) -> Pair <K , V >,
28
27
val toPersistentEntity : (key: K , value: V ) -> E ,
@@ -326,9 +325,9 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
326
325
}
327
326
328
327
// No one is writing, but we haven't looked in the database yet. This can only be when there are no writers.
329
- class Unknown <K , T >(private val map : AppendOnlyPersistentMapBase <K , T , * , * >,
330
- private val key : K ,
331
- private val _valueLoader : () -> T ? ) : Transactional<T>() {
328
+ class Unknown <K : Any , T >(private val map : AppendOnlyPersistentMapBase <K , T , * , * >,
329
+ private val key : K ,
330
+ private val _valueLoader : () -> T ? ) : Transactional<T>() {
332
331
override val value: T
333
332
get() = valueWithoutIsolationDelegate.value ? : throw NoSuchElementException (" Not present" )
334
333
override val isPresent: Boolean
@@ -351,22 +350,22 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
351
350
352
351
// Written in a transaction (uncommitted) somewhere, but there's a small window when this might be seen after commit,
353
352
// hence the committed flag.
354
- class InFlight <K , T >(private val map : AppendOnlyPersistentMapBase <K , T , * , * >,
355
- private val key : K ,
356
- val weight : Int ,
357
- private val _readerValueLoader : () -> T ? ,
358
- private val _writerValueLoader : () -> T = { throw IllegalAccessException ("No value loader provided") }) : Transactional<T>() {
353
+ class InFlight <K : Any , T >(private val map : AppendOnlyPersistentMapBase <K , T , * , * >,
354
+ private val key : K ,
355
+ val weight : Int ,
356
+ private val _readerValueLoader : () -> T ? ,
357
+ private val _writerValueLoader : () -> T = { throw IllegalAccessException ("No value loader provided") }) : Transactional<T>() {
359
358
360
359
// A flag to indicate this has now been committed, but hasn't yet been replaced with Committed. This also
361
360
// de-duplicates writes of the Committed value to the cache.
362
361
private val committed = AtomicBoolean (false )
363
362
364
363
// What to do if a non-writer needs to see the value and it hasn't yet been committed to the database.
365
364
// Can be updated into a no-op once evaluated.
366
- private val readerValueLoader = AtomicReference < () -> T ? > (_readerValueLoader )
365
+ private val readerValueLoader = AtomicReference (_readerValueLoader )
367
366
// What to do if a writer needs to see the value and it hasn't yet been committed to the database.
368
367
// Can be updated into a no-op once evaluated.
369
- private val writerValueLoader = AtomicReference < () -> T > (_writerValueLoader )
368
+ private val writerValueLoader = AtomicReference (_writerValueLoader )
370
369
371
370
fun alsoWrite (_value : T ) {
372
371
// Make the lazy loader the writers see actually just return the value that has been set.
@@ -382,11 +381,11 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
382
381
// and then stop saying the transaction is writing the key.
383
382
tx.onCommit {
384
383
strongMap.cache.asMap().computeIfPresent(strongKey) { _, transactional: Transactional <T > ->
385
- if (transactional is Transactional . InFlight <* , T >) {
384
+ if (transactional is InFlight <* , T >) {
386
385
transactional.committed.set(true )
387
386
val value = transactional.peekableValue
388
387
if (value != null ) {
389
- Transactional . Committed (value)
388
+ Committed (value)
390
389
} else {
391
390
transactional
392
391
}
@@ -447,7 +446,7 @@ abstract class AppendOnlyPersistentMapBase<K, V, E, out EK>(
447
446
}
448
447
449
448
// Open for tests to override
450
- open class AppendOnlyPersistentMap <K , V , E , out EK >(
449
+ open class AppendOnlyPersistentMap <K : Any , V , E , out EK >(
451
450
cacheFactory : NamedCacheFactory ,
452
451
name : String ,
453
452
toPersistentEntityKey : (K ) -> EK ,
@@ -466,7 +465,7 @@ open class AppendOnlyPersistentMap<K, V, E, out EK>(
466
465
}
467
466
468
467
// Same as above, but with weighted values (e.g. memory footprint sensitive).
469
- class WeightBasedAppendOnlyPersistentMap <K , V , E , out EK >(
468
+ class WeightBasedAppendOnlyPersistentMap <K : Any , V , E , out EK >(
470
469
cacheFactory : NamedCacheFactory ,
471
470
name : String ,
472
471
toPersistentEntityKey : (K ) -> EK ,
@@ -485,7 +484,7 @@ class WeightBasedAppendOnlyPersistentMap<K, V, E, out EK>(
485
484
override val cache = NonInvalidatingWeightBasedCache (
486
485
cacheFactory = cacheFactory,
487
486
name = name,
488
- weigher = Weigher { key, value: Transactional <V > ->
487
+ weigher = { key, value: Transactional <V > ->
489
488
value.shallowSize + if (value is Transactional .InFlight <* , * >) {
490
489
value.weight * 2
491
490
} else {
0 commit comments