Commit 3d3aae60d8e72600bf62efee391e7522b898e37b
Committed by
Andrew Shvayka
1 parent
d7f797a0
util: LinkedHashMapRemoveEldest refactored with BiConsumer
Showing
2 changed files
with
29 additions
and
37 deletions
@@ -36,48 +36,33 @@ import lombok.ToString; | @@ -36,48 +36,33 @@ import lombok.ToString; | ||
36 | 36 | ||
37 | import java.util.LinkedHashMap; | 37 | import java.util.LinkedHashMap; |
38 | import java.util.Map; | 38 | import java.util.Map; |
39 | +import java.util.function.BiConsumer; | ||
39 | 40 | ||
40 | /** | 41 | /** |
41 | - * HashMap that removed eldest (by put order) entries | 42 | + * LinkedHashMap that removed eldest entries (by insert order) |
42 | * It guaranteed that size is not greater then maxEntries parameter. And remove time is constant O(1). | 43 | * It guaranteed that size is not greater then maxEntries parameter. And remove time is constant O(1). |
43 | - * Use withMaxEntries to setup maxEntries. | ||
44 | - * Because overloaded constructor will look similar to LinkedHashMap(initCapacity) | ||
45 | * Example: | 44 | * Example: |
46 | - * new LinkedHashMapRemoveEldest<Long, String>().withMaxEntries(100L) | 45 | + * LinkedHashMapRemoveEldest<Long, String> map = |
46 | + * new LinkedHashMapRemoveEldest<>(MAX_ENTRIES, this::removeConsumer); | ||
47 | * */ | 47 | * */ |
48 | @Getter | 48 | @Getter |
49 | @ToString(callSuper = true) | 49 | @ToString(callSuper = true) |
50 | @EqualsAndHashCode(callSuper = true) | 50 | @EqualsAndHashCode(callSuper = true) |
51 | -public class LinkedHashMapRemoveEldest<K,V> extends LinkedHashMap<K,V> { | ||
52 | - long maxEntries = Long.MAX_VALUE; | 51 | +public class LinkedHashMapRemoveEldest<K, V> extends LinkedHashMap<K, V> { |
52 | + final long maxEntries; | ||
53 | + final BiConsumer<K, V> removeConsumer; | ||
53 | 54 | ||
54 | - public LinkedHashMapRemoveEldest() { | ||
55 | - super(); | ||
56 | - } | ||
57 | - | ||
58 | - public LinkedHashMapRemoveEldest(int initialCapacity) { | ||
59 | - super(initialCapacity); | ||
60 | - } | ||
61 | - | ||
62 | - public LinkedHashMapRemoveEldest(int initialCapacity, float loadFactor) { | ||
63 | - super(initialCapacity, loadFactor); | ||
64 | - } | ||
65 | - | ||
66 | - public LinkedHashMapRemoveEldest(Map<? extends K, ? extends V> m) { | ||
67 | - super(m); | ||
68 | - } | ||
69 | - | ||
70 | - public LinkedHashMapRemoveEldest(int initialCapacity, float loadFactor, boolean accessOrder) { | ||
71 | - super(initialCapacity, loadFactor, accessOrder); | ||
72 | - } | ||
73 | - | ||
74 | - public LinkedHashMapRemoveEldest<K,V> withMaxEntries(long maxEntries) { | 55 | + public LinkedHashMapRemoveEldest(long maxEntries, BiConsumer<K, V> removeConsumer) { |
75 | this.maxEntries = maxEntries; | 56 | this.maxEntries = maxEntries; |
76 | - return this; | 57 | + this.removeConsumer = removeConsumer; |
77 | } | 58 | } |
78 | 59 | ||
79 | @Override | 60 | @Override |
80 | - protected boolean removeEldestEntry(Map.Entry eldest) { | ||
81 | - return size() > maxEntries; | 61 | + protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { |
62 | + if (size() <= maxEntries) { | ||
63 | + return false; | ||
64 | + } | ||
65 | + removeConsumer.accept(eldest.getKey(), eldest.getValue()); | ||
66 | + return true; | ||
82 | } | 67 | } |
83 | } | 68 | } |
@@ -30,7 +30,7 @@ | @@ -30,7 +30,7 @@ | ||
30 | */ | 30 | */ |
31 | package org.thingsboard.common.util; | 31 | package org.thingsboard.common.util; |
32 | 32 | ||
33 | -import org.junit.Before; | 33 | +import org.hamcrest.Matchers; |
34 | import org.junit.Test; | 34 | import org.junit.Test; |
35 | 35 | ||
36 | import java.util.LinkedHashMap; | 36 | import java.util.LinkedHashMap; |
@@ -42,26 +42,33 @@ import static org.hamcrest.MatcherAssert.assertThat; | @@ -42,26 +42,33 @@ import static org.hamcrest.MatcherAssert.assertThat; | ||
42 | public class LinkedHashMapRemoveEldestTest { | 42 | public class LinkedHashMapRemoveEldestTest { |
43 | 43 | ||
44 | public static final long MAX_ENTRIES = 10L; | 44 | public static final long MAX_ENTRIES = 10L; |
45 | - LinkedHashMapRemoveEldest<Long, String> map; | 45 | + long removeCount = 0; |
46 | 46 | ||
47 | - @Before | ||
48 | - public void setUp() throws Exception { | ||
49 | - map = new LinkedHashMapRemoveEldest<Long, String>().withMaxEntries(MAX_ENTRIES); | 47 | + void removeConsumer(Long id, String name) { |
48 | + removeCount++; | ||
49 | + assertThat(id, is(Matchers.lessThan(MAX_ENTRIES))); | ||
50 | + assertThat(name, is(id.toString())); | ||
50 | } | 51 | } |
51 | 52 | ||
52 | @Test | 53 | @Test |
53 | public void givenMap_whenOverSized_thenVerifyRemovedEldest() { | 54 | public void givenMap_whenOverSized_thenVerifyRemovedEldest() { |
55 | + //given | ||
56 | + LinkedHashMapRemoveEldest<Long, String> map = | ||
57 | + new LinkedHashMapRemoveEldest<>(MAX_ENTRIES, this::removeConsumer); | ||
58 | + | ||
54 | assertThat(map.getMaxEntries(), is(MAX_ENTRIES)); | 59 | assertThat(map.getMaxEntries(), is(MAX_ENTRIES)); |
55 | assertThat(map, instanceOf(LinkedHashMap.class)); | 60 | assertThat(map, instanceOf(LinkedHashMap.class)); |
56 | assertThat(map, instanceOf(LinkedHashMapRemoveEldest.class)); | 61 | assertThat(map, instanceOf(LinkedHashMapRemoveEldest.class)); |
57 | assertThat(map.size(), is(0)); | 62 | assertThat(map.size(), is(0)); |
58 | 63 | ||
64 | + //when | ||
59 | for (long i = 0; i < MAX_ENTRIES * 2; i++) { | 65 | for (long i = 0; i < MAX_ENTRIES * 2; i++) { |
60 | map.put(i, String.valueOf(i)); | 66 | map.put(i, String.valueOf(i)); |
61 | } | 67 | } |
62 | 68 | ||
63 | - assertThat(map.size(), is((int) MAX_ENTRIES)); | ||
64 | - | 69 | + //then |
70 | + assertThat((long) map.size(), is(MAX_ENTRIES)); | ||
71 | + assertThat(removeCount, is(MAX_ENTRIES)); | ||
65 | for (long i = MAX_ENTRIES; i < MAX_ENTRIES * 2; i++) { | 72 | for (long i = MAX_ENTRIES; i < MAX_ENTRIES * 2; i++) { |
66 | assertThat(map.get(i), is(String.valueOf(i))); | 73 | assertThat(map.get(i), is(String.valueOf(i))); |
67 | } | 74 | } |