diff --git a/src/main/kotlin/io/emeraldpay/dshackle/data/RingSet.kt b/src/main/kotlin/io/emeraldpay/dshackle/data/RingSet.kt index 37b37af4..26a03a5b 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/data/RingSet.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/data/RingSet.kt @@ -5,40 +5,36 @@ import java.util.concurrent.atomic.AtomicReference class RingSet( private val maxSize: Int ) : Set { - private var seqValues: AtomicReference> = AtomicReference(emptyList()) - private var set: Set = emptySet() + private var setRef: AtomicReference> = AtomicReference(LinkedHashSet()) override val size: Int - get() = set.size + get() = setRef.get().size fun add(element: T) { - if (set.contains(element)) { - return - } - seqValues.getAndUpdate { vals -> - vals.let { - if (vals.size > maxSize) { - vals.drop(1) - } else { - vals + setRef.getAndUpdate { set -> + if (!set.contains(element)) { + val copyset = LinkedHashSet(set) + copyset.add(element) + if (copyset.size > maxSize) { + copyset.remove(set.elementAt(0)) } - }.plus(element).let { - set = HashSet(it) - it + copyset + } else { + set } } } override fun isEmpty(): Boolean { - return set.isEmpty() + return setRef.get().isEmpty() } override fun contains(element: @UnsafeVariance T): Boolean { - return set.contains(element) + return setRef.get().contains(element) } override fun iterator(): Iterator { - return set.iterator() + return setRef.get().iterator() } override fun containsAll(elements: Collection<@UnsafeVariance T>): Boolean { - return set.containsAll(elements) + return setRef.get().containsAll(elements) } } diff --git a/src/main/kotlin/io/emeraldpay/dshackle/upstream/forkchoice/NoChoiceWithPriorityForkChoice.kt b/src/main/kotlin/io/emeraldpay/dshackle/upstream/forkchoice/NoChoiceWithPriorityForkChoice.kt index 177ae220..951647dd 100644 --- a/src/main/kotlin/io/emeraldpay/dshackle/upstream/forkchoice/NoChoiceWithPriorityForkChoice.kt +++ b/src/main/kotlin/io/emeraldpay/dshackle/upstream/forkchoice/NoChoiceWithPriorityForkChoice.kt @@ -9,7 +9,7 @@ class NoChoiceWithPriorityForkChoice( private val nodeRating: Int ) : ForkChoice { private val head = AtomicReference(null) - private val seenBlocks = RingSet(10) + private val seenBlocks = RingSet(100) override fun getHead(): BlockContainer? { return head.get()