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 'org.apache.commons:commons-collections4:4.3'
implementation 'javax.annotation:javax.annotation-api:1.3.2' implementation 'javax.annotation:javax.annotation-api:1.3.2'
implementation 'org.bouncycastle:bcprov-jdk15on:1.61' 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.slf4j:slf4j-api:$slf4jVersion"
implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.11.1" implementation "org.apache.logging.log4j:log4j-slf4j-impl:2.11.1"

View File

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

View File

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