diff --git a/common/util/src/main/java/org/thingsboard/common/util/LinkedHashMapRemoveEldest.java b/common/util/src/main/java/org/thingsboard/common/util/LinkedHashMapRemoveEldest.java index 7f91da737b..c1e28ca4c9 100644 --- a/common/util/src/main/java/org/thingsboard/common/util/LinkedHashMapRemoveEldest.java +++ b/common/util/src/main/java/org/thingsboard/common/util/LinkedHashMapRemoveEldest.java @@ -36,48 +36,33 @@ import lombok.ToString; import java.util.LinkedHashMap; import java.util.Map; +import java.util.function.BiConsumer; /** - * HashMap that removed eldest (by put order) entries + * LinkedHashMap that removed eldest entries (by insert order) * It guaranteed that size is not greater then maxEntries parameter. And remove time is constant O(1). - * Use withMaxEntries to setup maxEntries. - * Because overloaded constructor will look similar to LinkedHashMap(initCapacity) * Example: - * new LinkedHashMapRemoveEldest().withMaxEntries(100L) + * LinkedHashMapRemoveEldest map = + * new LinkedHashMapRemoveEldest<>(MAX_ENTRIES, this::removeConsumer); * */ @Getter @ToString(callSuper = true) @EqualsAndHashCode(callSuper = true) -public class LinkedHashMapRemoveEldest extends LinkedHashMap { - long maxEntries = Long.MAX_VALUE; +public class LinkedHashMapRemoveEldest extends LinkedHashMap { + final long maxEntries; + final BiConsumer removeConsumer; - public LinkedHashMapRemoveEldest() { - super(); - } - - public LinkedHashMapRemoveEldest(int initialCapacity) { - super(initialCapacity); - } - - public LinkedHashMapRemoveEldest(int initialCapacity, float loadFactor) { - super(initialCapacity, loadFactor); - } - - public LinkedHashMapRemoveEldest(Map m) { - super(m); - } - - public LinkedHashMapRemoveEldest(int initialCapacity, float loadFactor, boolean accessOrder) { - super(initialCapacity, loadFactor, accessOrder); - } - - public LinkedHashMapRemoveEldest withMaxEntries(long maxEntries) { + public LinkedHashMapRemoveEldest(long maxEntries, BiConsumer removeConsumer) { this.maxEntries = maxEntries; - return this; + this.removeConsumer = removeConsumer; } @Override - protected boolean removeEldestEntry(Map.Entry eldest) { - return size() > maxEntries; + protected boolean removeEldestEntry(Map.Entry eldest) { + if (size() <= maxEntries) { + return false; + } + removeConsumer.accept(eldest.getKey(), eldest.getValue()); + return true; } } diff --git a/common/util/src/test/java/org/thingsboard/common/util/LinkedHashMapRemoveEldestTest.java b/common/util/src/test/java/org/thingsboard/common/util/LinkedHashMapRemoveEldestTest.java index 4dad070ec4..62d7f788af 100644 --- a/common/util/src/test/java/org/thingsboard/common/util/LinkedHashMapRemoveEldestTest.java +++ b/common/util/src/test/java/org/thingsboard/common/util/LinkedHashMapRemoveEldestTest.java @@ -30,7 +30,7 @@ */ package org.thingsboard.common.util; -import org.junit.Before; +import org.hamcrest.Matchers; import org.junit.Test; import java.util.LinkedHashMap; @@ -42,26 +42,33 @@ import static org.hamcrest.MatcherAssert.assertThat; public class LinkedHashMapRemoveEldestTest { public static final long MAX_ENTRIES = 10L; - LinkedHashMapRemoveEldest map; + long removeCount = 0; - @Before - public void setUp() throws Exception { - map = new LinkedHashMapRemoveEldest().withMaxEntries(MAX_ENTRIES); + void removeConsumer(Long id, String name) { + removeCount++; + assertThat(id, is(Matchers.lessThan(MAX_ENTRIES))); + assertThat(name, is(id.toString())); } @Test public void givenMap_whenOverSized_thenVerifyRemovedEldest() { + //given + LinkedHashMapRemoveEldest map = + new LinkedHashMapRemoveEldest<>(MAX_ENTRIES, this::removeConsumer); + assertThat(map.getMaxEntries(), is(MAX_ENTRIES)); assertThat(map, instanceOf(LinkedHashMap.class)); assertThat(map, instanceOf(LinkedHashMapRemoveEldest.class)); assertThat(map.size(), is(0)); + //when for (long i = 0; i < MAX_ENTRIES * 2; i++) { map.put(i, String.valueOf(i)); } - assertThat(map.size(), is((int) MAX_ENTRIES)); - + //then + assertThat((long) map.size(), is(MAX_ENTRIES)); + assertThat(removeCount, is(MAX_ENTRIES)); for (long i = MAX_ENTRIES; i < MAX_ENTRIES * 2; i++) { assertThat(map.get(i), is(String.valueOf(i))); }