This is an automated email from the ASF dual-hosted git repository.
toulmean pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-tuweni.git
The following commit(s) were added to refs/heads/main by this push:
new f3b275b use ExpiringMaps instead of HashMaps for EthClient and
EthClient66
new 96d7ff8 Merge pull request #359 from atoulme/expiring_maps_eth_client
f3b275b is described below
commit f3b275b5970d9c4c38aefb7d3fb67d15eb6dae8c
Author: Antoine Toulme <[email protected]>
AuthorDate: Mon Jan 10 21:22:50 2022 -0800
use ExpiringMaps instead of HashMaps for EthClient and EthClient66
---
.../org/apache/tuweni/concurrent/ExpiringMap.java | 37 ++++++++++++++--------
.../apache/tuweni/concurrent/ExpiringMapTest.java | 10 +++++-
.../org/apache/tuweni/devp2p/eth/EthClient.kt | 9 +++---
.../org/apache/tuweni/devp2p/eth/EthClient66.kt | 9 +++---
4 files changed, 43 insertions(+), 22 deletions(-)
diff --git
a/concurrent/src/main/java/org/apache/tuweni/concurrent/ExpiringMap.java
b/concurrent/src/main/java/org/apache/tuweni/concurrent/ExpiringMap.java
index dfa82a0..4605de9 100644
--- a/concurrent/src/main/java/org/apache/tuweni/concurrent/ExpiringMap.java
+++ b/concurrent/src/main/java/org/apache/tuweni/concurrent/ExpiringMap.java
@@ -62,17 +62,28 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
private final ConcurrentHashMap<K, ExpiringEntry<K, V>> storage = new
ConcurrentHashMap<>();
private final PriorityBlockingQueue<ExpiringEntry<K, V>> expiryQueue = new
PriorityBlockingQueue<>();
private final LongSupplier currentTimeSupplier;
+ private final Long defaultTimeout;
/**
* Construct an empty map.
*/
public ExpiringMap() {
- this(System::currentTimeMillis);
+ this(System::currentTimeMillis, Long.MAX_VALUE);
+ }
+
+ /**
+ * Construct a map with a default timeout value.
+ *
+ * @param defaultTimeout the default timeout in milliseconds
+ */
+ public ExpiringMap(Long defaultTimeout) {
+ this(System::currentTimeMillis, defaultTimeout);
}
@VisibleForTesting
- ExpiringMap(LongSupplier currentTimeSupplier) {
+ ExpiringMap(LongSupplier currentTimeSupplier, Long defaultTimeout) {
this.currentTimeSupplier = currentTimeSupplier;
+ this.defaultTimeout = defaultTimeout;
}
@Nullable
@@ -122,7 +133,7 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
requireNonNull(key);
requireNonNull(value);
purgeExpired();
- ExpiringEntry<K, V> oldEntry = storage.put(key, new ExpiringEntry<>(key,
value, Long.MAX_VALUE, null));
+ ExpiringEntry<K, V> oldEntry = storage.put(key, new ExpiringEntry<>(key,
value, defaultTimeout, null));
return (oldEntry == null) ? null : oldEntry.value;
}
@@ -185,7 +196,7 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
requireNonNull(m);
purgeExpired();
for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
- storage.put(e.getKey(), new ExpiringEntry<>(e.getKey(), e.getValue(),
Long.MAX_VALUE, null));
+ storage.put(e.getKey(), new ExpiringEntry<>(e.getKey(), e.getValue(),
defaultTimeout, null));
}
}
@@ -195,7 +206,7 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
requireNonNull(key);
requireNonNull(value);
purgeExpired();
- ExpiringEntry<K, V> oldEntry = storage.putIfAbsent(key, new
ExpiringEntry<>(key, value, Long.MAX_VALUE, null));
+ ExpiringEntry<K, V> oldEntry = storage.putIfAbsent(key, new
ExpiringEntry<>(key, value, defaultTimeout, null));
return (oldEntry == null) ? null : oldEntry.value;
}
@@ -259,14 +270,14 @@ public final class ExpiringMap<K, V> implements Map<K, V>
{
}
V oldValue = (oldEntry == null) ? null : oldEntry.value;
V newValue = remappingFunction.apply(k, oldValue);
- return (newValue == null) ? null : new ExpiringEntry<>(k, newValue,
Long.MAX_VALUE, null);
+ return (newValue == null) ? null : new ExpiringEntry<>(k, newValue,
defaultTimeout, null);
});
return (newEntry == null) ? null : newEntry.value;
}
@Override
public V computeIfAbsent(K key, Function<? super K, ? extends V>
mappingFunction) {
- return computeIfAbsent(key, Long.MAX_VALUE, mappingFunction);
+ return computeIfAbsent(key, defaultTimeout, mappingFunction);
}
public V computeIfAbsent(K key, long expiration, Function<? super K, ?
extends V> mappingFunction) {
@@ -284,7 +295,7 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
expiryQueue.remove(oldEntry);
}
V newValue = remappingFunction.apply(k, oldEntry.value);
- return (newValue == null) ? null : new ExpiringEntry<>(k, newValue,
Long.MAX_VALUE, null);
+ return (newValue == null) ? null : new ExpiringEntry<>(k, newValue,
defaultTimeout, null);
});
return (newEntry == null) ? null : newEntry.value;
}
@@ -292,19 +303,19 @@ public final class ExpiringMap<K, V> implements Map<K, V>
{
@Override
public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V>
remappingFunction) {
ExpiringEntry<K, V> entry =
- storage.merge(key, new ExpiringEntry<>(key, value, Long.MAX_VALUE,
null), (oldEntry, newEntry) -> {
+ storage.merge(key, new ExpiringEntry<>(key, value, defaultTimeout,
null), (oldEntry, newEntry) -> {
if (oldEntry.expiry < Long.MAX_VALUE) {
expiryQueue.remove(oldEntry);
}
V newValue = remappingFunction.apply(oldEntry.value, newEntry.value);
- return (newValue == null) ? null : new ExpiringEntry<>(key,
newValue, Long.MAX_VALUE, null);
+ return (newValue == null) ? null : new ExpiringEntry<>(key,
newValue, defaultTimeout, null);
});
return (entry == null) ? null : entry.value;
}
@Override
public V replace(K key, V value) {
- ExpiringEntry<K, V> oldEntry = storage.replace(key, new
ExpiringEntry<>(key, value, Long.MAX_VALUE, null));
+ ExpiringEntry<K, V> oldEntry = storage.replace(key, new
ExpiringEntry<>(key, value, defaultTimeout, null));
if (oldEntry != null) {
if (oldEntry.expiry < Long.MAX_VALUE) {
expiryQueue.remove(oldEntry);
@@ -323,7 +334,7 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
if (oldEntry.expiry < Long.MAX_VALUE) {
expiryQueue.remove(oldEntry);
}
- return new ExpiringEntry<>(k, newValue, Long.MAX_VALUE, null);
+ return new ExpiringEntry<>(k, newValue, defaultTimeout, null);
}
return oldEntry;
});
@@ -336,7 +347,7 @@ public final class ExpiringMap<K, V> implements Map<K, V> {
if (oldEntry.expiry < Long.MAX_VALUE) {
expiryQueue.remove(oldEntry);
}
- return new ExpiringEntry<>(k, requireNonNull(function.apply(k,
oldEntry.value)), Long.MAX_VALUE, null);
+ return new ExpiringEntry<>(k, requireNonNull(function.apply(k,
oldEntry.value)), defaultTimeout, null);
});
}
diff --git
a/concurrent/src/test/java/org/apache/tuweni/concurrent/ExpiringMapTest.java
b/concurrent/src/test/java/org/apache/tuweni/concurrent/ExpiringMapTest.java
index 8e6e800..df98197 100644
--- a/concurrent/src/test/java/org/apache/tuweni/concurrent/ExpiringMapTest.java
+++ b/concurrent/src/test/java/org/apache/tuweni/concurrent/ExpiringMapTest.java
@@ -32,7 +32,7 @@ class ExpiringMapTest {
@BeforeEach
void setup() {
currentTime = Instant.now();
- map = new ExpiringMap<>(() -> currentTime.toEpochMilli());
+ map = new ExpiringMap<>(() -> currentTime.toEpochMilli(), Long.MAX_VALUE);
}
@Test
@@ -168,4 +168,12 @@ class ExpiringMapTest {
assertTrue(called.get());
assertEquals(new ExpiringMap<Integer, String>(), new ExpiringMap<Integer,
String>());
}
+
+ @Test
+ void testUsesDefaultTimeout() throws InterruptedException {
+ ExpiringMap<String, String> map = new ExpiringMap<>(10L);
+ map.put("foo", "bar");
+ Thread.sleep(11);
+ assertEquals("bar", map.get("foo"));
+ }
}
diff --git
a/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient.kt
b/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient.kt
index 82032ae..5a784c4 100644
--- a/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient.kt
+++ b/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient.kt
@@ -18,6 +18,7 @@ package org.apache.tuweni.devp2p.eth
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.concurrent.AsyncResult
+import org.apache.tuweni.concurrent.ExpiringMap
import org.apache.tuweni.eth.Block
import org.apache.tuweni.eth.BlockBody
import org.apache.tuweni.eth.BlockHeader
@@ -42,10 +43,10 @@ open class EthClient(
) :
EthRequestsManager, SubProtocolClient {
- private val headerRequests = HashMap<String, Request<List<BlockHeader>>>()
- private val bodiesRequests = HashMap<String, Request<List<BlockBody>>>()
- private val nodeDataRequests = HashMap<String, Request<List<Bytes?>>>()
- private val transactionReceiptRequests = HashMap<String,
Request<List<List<TransactionReceipt>>>>()
+ private val headerRequests = ExpiringMap<String,
Request<List<BlockHeader>>>(600000)
+ private val bodiesRequests = ExpiringMap<String,
Request<List<BlockBody>>>(600000)
+ private val nodeDataRequests = ExpiringMap<String,
Request<List<Bytes?>>>(600000)
+ private val transactionReceiptRequests = ExpiringMap<String,
Request<List<List<TransactionReceipt>>>>(600000)
override fun connectionSelectionStrategy() = connectionSelectionStrategy
diff --git
a/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient66.kt
b/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient66.kt
index 5e144de..63a43e4 100644
--- a/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient66.kt
+++ b/devp2p-eth/src/main/kotlin/org/apache/tuweni/devp2p/eth/EthClient66.kt
@@ -18,6 +18,7 @@ package org.apache.tuweni.devp2p.eth
import org.apache.tuweni.bytes.Bytes
import org.apache.tuweni.concurrent.AsyncResult
+import org.apache.tuweni.concurrent.ExpiringMap
import org.apache.tuweni.eth.Block
import org.apache.tuweni.eth.BlockBody
import org.apache.tuweni.eth.BlockHeader
@@ -45,10 +46,10 @@ class EthClient66(
val logger = LoggerFactory.getLogger(EthClient66::class.java)
}
- private val headerRequests = mutableMapOf<Bytes,
Request<List<BlockHeader>>>()
- private val bodiesRequests = HashMap<Bytes, Request<List<BlockBody>>>()
- private val nodeDataRequests = HashMap<Bytes, Request<List<Bytes?>>>()
- private val transactionReceiptRequests = HashMap<Bytes,
Request<List<List<TransactionReceipt>>>>()
+ private val headerRequests = ExpiringMap<Bytes,
Request<List<BlockHeader>>>(600000)
+ private val bodiesRequests = ExpiringMap<Bytes,
Request<List<BlockBody>>>(600000)
+ private val nodeDataRequests = ExpiringMap<Bytes,
Request<List<Bytes?>>>(600000)
+ private val transactionReceiptRequests = ExpiringMap<Bytes,
Request<List<List<TransactionReceipt>>>>(600000)
override fun connectionSelectionStrategy() = connectionSelectionStrategy
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]