problem: block height cache doesn't evict when old blocks are added

rel: ce010e50
This commit is contained in:
Igor Artamonov
2020-07-20 21:25:31 -04:00
parent ce010e50ce
commit 0d1980ce70
3 changed files with 16 additions and 20 deletions

View File

@@ -104,6 +104,7 @@ dependencies {
implementation 'org.apache.commons:commons-collections4:4.3'
implementation 'javax.annotation:javax.annotation-api:1.3.2'
implementation 'org.bouncycastle:bcprov-jdk15on:1.61'
implementation 'com.github.ben-manes.caffeine:caffeine:2.8.5'
implementation "org.slf4j:slf4j-api:$slf4jVersion"
implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.11.1"

View File

@@ -15,41 +15,35 @@
*/
package io.emeraldpay.dshackle.cache
import com.github.benmanes.caffeine.cache.Caffeine
import io.emeraldpay.dshackle.data.BlockContainer
import io.emeraldpay.dshackle.data.BlockId
import io.emeraldpay.dshackle.reader.Reader
import org.slf4j.LoggerFactory
import reactor.core.publisher.Mono
import java.util.concurrent.ConcurrentHashMap
/**
* Memory cache for blocks heights, keeps mapping height->hash.
*/
open class HeightCache(
val maxSize: Int = 256
maxSize: Int = 512
) : Reader<Long, BlockId> {
companion object {
private val log = LoggerFactory.getLogger(HeightCache::class.java)
}
private val heights = ConcurrentHashMap<Long, BlockId>()
private val heights = Caffeine.newBuilder()
.maximumSize(maxSize.toLong())
.build<Long, BlockId>()
override fun read(key: Long): Mono<BlockId> {
return Mono.justOrEmpty(heights[key])
return Mono.justOrEmpty(heights.getIfPresent(key))
}
open fun add(block: BlockContainer): BlockId? {
val existing = heights[block.height]
heights[block.height] = block.hash
// evict old numbers if full
var dropHeight = block.height - maxSize
while (heights.size > maxSize && dropHeight < block.height) {
heights.remove(dropHeight)
dropHeight++
}
return existing
val previousId = heights.getIfPresent(block.height)
heights.put(block.height, block.hash)
return previousId
}
fun purge() {
heights.cleanUp()
}
}

View File

@@ -72,6 +72,7 @@ class HeightCacheSpec extends Specification {
block.timestamp = Instant.now()
cache.add(BlockContainer.from(block))
}
cache.purge()
def act1 = cache.read(100).block()
def act2 = cache.read(101).block()