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 <anto...@lunar-ocean.com>
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: commits-unsubscr...@tuweni.apache.org
For additional commands, e-mail: commits-h...@tuweni.apache.org

Reply via email to