Commit 3d3aae60d8e72600bf62efee391e7522b898e37b

Authored by Sergey Matvienko
Committed by Andrew Shvayka
1 parent d7f797a0

util: LinkedHashMapRemoveEldest refactored with BiConsumer

... ... @@ -36,48 +36,33 @@ import lombok.ToString;
36 36
37 37 import java.util.LinkedHashMap;
38 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 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 44 * Example:
46   - * new LinkedHashMapRemoveEldest<Long, String>().withMaxEntries(100L)
  45 + * LinkedHashMapRemoveEldest<Long, String> map =
  46 + * new LinkedHashMapRemoveEldest<>(MAX_ENTRIES, this::removeConsumer);
47 47 * */
48 48 @Getter
49 49 @ToString(callSuper = true)
50 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 56 this.maxEntries = maxEntries;
76   - return this;
  57 + this.removeConsumer = removeConsumer;
77 58 }
78 59
79 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 30 */
31 31 package org.thingsboard.common.util;
32 32
33   -import org.junit.Before;
  33 +import org.hamcrest.Matchers;
34 34 import org.junit.Test;
35 35
36 36 import java.util.LinkedHashMap;
... ... @@ -42,26 +42,33 @@ import static org.hamcrest.MatcherAssert.assertThat;
42 42 public class LinkedHashMapRemoveEldestTest {
43 43
44 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 53 @Test
53 54 public void givenMap_whenOverSized_thenVerifyRemovedEldest() {
  55 + //given
  56 + LinkedHashMapRemoveEldest<Long, String> map =
  57 + new LinkedHashMapRemoveEldest<>(MAX_ENTRIES, this::removeConsumer);
  58 +
54 59 assertThat(map.getMaxEntries(), is(MAX_ENTRIES));
55 60 assertThat(map, instanceOf(LinkedHashMap.class));
56 61 assertThat(map, instanceOf(LinkedHashMapRemoveEldest.class));
57 62 assertThat(map.size(), is(0));
58 63
  64 + //when
59 65 for (long i = 0; i < MAX_ENTRIES * 2; i++) {
60 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 72 for (long i = MAX_ENTRIES; i < MAX_ENTRIES * 2; i++) {
66 73 assertThat(map.get(i), is(String.valueOf(i)));
67 74 }
... ...