-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
352 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
75 changes: 75 additions & 0 deletions
75
src/main/java/info/unterrainer/commons/jreutils/collections/DataMap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package info.unterrainer.commons.jreutils.collections; | ||
|
||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Map.Entry; | ||
import java.util.Set; | ||
|
||
import lombok.NoArgsConstructor; | ||
|
||
@NoArgsConstructor | ||
public class DataMap<K, V> { | ||
|
||
private SizeLimitedHashMap<K, V> map; | ||
|
||
public DataMap(final int maxSize) { | ||
map = new SizeLimitedHashMap<>(maxSize); | ||
} | ||
|
||
public synchronized DataMap<K, V> put(final K key, final V value) { | ||
map.put(key, value); | ||
return this; | ||
} | ||
|
||
public synchronized Collection<V> values() { | ||
return map.values(); | ||
} | ||
|
||
public synchronized Set<K> keySet() { | ||
return map.keySet(); | ||
} | ||
|
||
public synchronized Set<Entry<K, V>> entrySet() { | ||
return map.entrySet(); | ||
} | ||
|
||
public synchronized boolean containsKey(final Object key) { | ||
return map.containsKey(key); | ||
} | ||
|
||
public synchronized boolean containsValue(final Object value) { | ||
return map.containsValue(value); | ||
} | ||
|
||
public synchronized boolean isEmpty() { | ||
return map.isEmpty(); | ||
} | ||
|
||
public synchronized void clear() { | ||
map.clear(); | ||
} | ||
|
||
public synchronized V get(final K key) { | ||
return map.get(key); | ||
} | ||
|
||
public synchronized V remove(final K key) { | ||
return map.remove(key); | ||
} | ||
|
||
public synchronized int size() { | ||
return map.size(); | ||
} | ||
|
||
public synchronized Map<K, V> getMapClone() { | ||
return new HashMap<>(map); | ||
} | ||
|
||
public synchronized Map<K, V> getMapCloneAndClear() { | ||
Map<K, V> clone; | ||
clone = new HashMap<>(map); | ||
map.clear(); | ||
return clone; | ||
} | ||
} |
60 changes: 60 additions & 0 deletions
60
src/main/java/info/unterrainer/commons/jreutils/collections/DataQueue.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
package info.unterrainer.commons.jreutils.collections; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Collection; | ||
import java.util.List; | ||
|
||
import org.apache.commons.collections4.queue.CircularFifoQueue; | ||
|
||
public class DataQueue<T> { | ||
|
||
private CircularFifoQueue<T> queue; | ||
|
||
public DataQueue(final int maxSize) { | ||
this(maxSize, (Collection<T>) null); | ||
} | ||
|
||
public DataQueue(final int maxSize, final Collection<T> collection) { | ||
queue = new CircularFifoQueue<>(maxSize); | ||
if (collection != null) | ||
for (T element : collection) | ||
queue.offer(element); | ||
} | ||
|
||
public DataQueue(final int maxSize, final T[] array) { | ||
queue = new CircularFifoQueue<>(maxSize); | ||
if (array != null) | ||
for (T element : array) | ||
queue.offer(element); | ||
} | ||
|
||
public synchronized DataQueue<T> offer(final T element) { | ||
queue.offer(element); | ||
return this; | ||
} | ||
|
||
public synchronized T poll() { | ||
return queue.poll(); | ||
} | ||
|
||
public synchronized T peek() { | ||
return queue.peek(); | ||
} | ||
|
||
public synchronized void clear() { | ||
queue.clear(); | ||
} | ||
|
||
public synchronized List<T> getListClone() { | ||
List<T> list = new ArrayList<>(); | ||
list.addAll(queue); | ||
return list; | ||
} | ||
|
||
public synchronized List<T> getListCloneAndClear() { | ||
List<T> list = new ArrayList<>(); | ||
list.addAll(queue); | ||
queue.clear(); | ||
return list; | ||
} | ||
} |
109 changes: 109 additions & 0 deletions
109
src/main/java/info/unterrainer/commons/jreutils/collections/DataTable.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
package info.unterrainer.commons.jreutils.collections; | ||
|
||
import java.lang.reflect.Array; | ||
import java.util.Collection; | ||
import java.util.HashMap; | ||
import java.util.Set; | ||
import java.util.function.Function; | ||
|
||
import lombok.Getter; | ||
import lombok.experimental.Accessors; | ||
|
||
@Accessors(fluent = true) | ||
public class DataTable<T> { | ||
|
||
private Class<T> clazz; | ||
private int maxEntries; | ||
@Getter | ||
private DataQueue<T> queue; | ||
|
||
private HashMap<String, Function<T, Object>> keySuppliers = new HashMap<>(); | ||
private HashMap<String, DataMap<Object, T>> maps = new HashMap<>(); | ||
|
||
public DataTable(final Class<T> clazz, final int maxEntries) { | ||
this.clazz = clazz; | ||
this.maxEntries = maxEntries; | ||
queue = new DataQueue<>(maxEntries); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <K> DataTable<T> addIndex(final String name, final Function<T, K> keySupplier) { | ||
keySuppliers.put(name, (Function<T, Object>) keySupplier); | ||
maps.put(name, new DataMap<Object, T>(maxEntries)); | ||
return this; | ||
} | ||
|
||
public synchronized T peek() { | ||
return queue.peek(); | ||
} | ||
|
||
public synchronized T poll() { | ||
T e = queue.poll(); | ||
for (String name : keySuppliers.keySet()) { | ||
Function<T, ?> func = keySuppliers.get(name); | ||
DataMap<Object, T> map = maps.get(name); | ||
map.remove(func.apply(e)); | ||
} | ||
return e; | ||
} | ||
|
||
public synchronized <K> T get(final String name, final K key) { | ||
return maps.get(name).get(key); | ||
} | ||
|
||
public synchronized void add(final T element) { | ||
queue.offer(element); | ||
for (String name : keySuppliers.keySet()) { | ||
Function<T, ?> func = keySuppliers.get(name); | ||
DataMap<Object, T> map = maps.get(name); | ||
Object key = func.apply(element); | ||
map.put(key, element); | ||
} | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public synchronized <K> Set<K> keySet(final String name) { | ||
return (Set<K>) maps.get(name).keySet(); | ||
} | ||
|
||
public synchronized Collection<T> values(final String name) { | ||
return maps.get(name).values(); | ||
} | ||
|
||
public synchronized boolean containsValue(final String name, final T value) { | ||
return maps.get(name).containsValue(value); | ||
} | ||
|
||
public synchronized <K> boolean containsKey(final String name, final K value) { | ||
return maps.get(name).containsKey(value); | ||
} | ||
|
||
public synchronized void clear() { | ||
queue.clear(); | ||
for (String name : keySuppliers.keySet()) | ||
maps.get(name).clear(); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public synchronized DataTable<T> load(T[] backingArray) { | ||
if (backingArray == null) | ||
backingArray = (T[]) Array.newInstance(clazz, 0); | ||
|
||
queue = new DataQueue<>(maxEntries, backingArray); | ||
|
||
for (String name : keySuppliers.keySet()) { | ||
DataMap<Object, T> map = new DataMap<>(maxEntries); | ||
maps.put(name, map); | ||
Function<T, ?> func = keySuppliers.get(name); | ||
for (T s : backingArray) | ||
map.put(func.apply(s), s); | ||
} | ||
return this; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public synchronized T[] toArray() { | ||
T[] zeroArray = (T[]) Array.newInstance(clazz, 0); | ||
return queue.getListClone().toArray(zeroArray); | ||
} | ||
} |
20 changes: 20 additions & 0 deletions
20
src/main/java/info/unterrainer/commons/jreutils/collections/SizeLimitedHashMap.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package info.unterrainer.commons.jreutils.collections; | ||
|
||
|
||
import java.util.LinkedHashMap; | ||
import java.util.Map; | ||
|
||
public class SizeLimitedHashMap<K, V> extends LinkedHashMap<K, V> { | ||
private static final long serialVersionUID = 6994714918898609875L; | ||
|
||
private final int maxSize; | ||
|
||
public SizeLimitedHashMap(final int maxSize) { | ||
this.maxSize = maxSize; | ||
} | ||
|
||
@Override | ||
protected boolean removeEldestEntry(final Map.Entry<K, V> eldest) { | ||
return size() > maxSize; | ||
} | ||
} |
79 changes: 79 additions & 0 deletions
79
src/test/java/info/unterrainer/commons/jreutils/collections/DataTableTests.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
package info.unterrainer.commons.jreutils.collections; | ||
|
||
import static org.assertj.core.api.Assertions.assertThat; | ||
|
||
import org.junit.jupiter.api.Test; | ||
|
||
public class DataTableTests { | ||
|
||
@Test | ||
public void peekingWorks() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.add("test"); | ||
assertThat(dt.peek()).isEqualTo("test"); | ||
} | ||
|
||
@Test | ||
public void pollingWorks() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.add("test"); | ||
assertThat(dt.poll()).isEqualTo("test"); | ||
} | ||
|
||
@Test | ||
public void clearingWorks() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.add("test"); | ||
dt.clear(); | ||
assertThat(dt.peek()).isNull(); | ||
assertThat(dt.poll()).isNull(); | ||
} | ||
|
||
@Test | ||
public void addingIndexWorks() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.addIndex("index1", e -> e); | ||
} | ||
|
||
@Test | ||
public void addingWorksWithIndex() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.addIndex("index1", e -> e); | ||
dt.add("test"); | ||
assertThat(dt.get("index1", "test")).isEqualTo("test"); | ||
} | ||
|
||
@Test | ||
public void addingWorksWithTwoIndexes() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.addIndex("index1", e -> e); | ||
dt.addIndex("index2", e -> e); | ||
dt.add("test"); | ||
assertThat(dt.get("index1", "test")).isEqualTo("test"); | ||
assertThat(dt.get("index2", "test")).isEqualTo("test"); | ||
} | ||
|
||
@Test | ||
public void deletingFromQueueAlsoDeletesFromAllIndexes() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.addIndex("index1", e -> e); | ||
dt.addIndex("index2", e -> e); | ||
dt.add("test"); | ||
dt.poll(); | ||
assertThat(dt.get("index1", "test")).isNull(); | ||
assertThat(dt.get("index2", "test")).isNull(); | ||
} | ||
|
||
@Test | ||
public void clearingWorksWithTwoIndexes() { | ||
DataTable<String> dt = new DataTable<>(String.class, 10); | ||
dt.addIndex("index1", e -> e); | ||
dt.addIndex("index2", e -> e); | ||
dt.add("test"); | ||
dt.clear(); | ||
assertThat(dt.peek()).isNull(); | ||
assertThat(dt.poll()).isNull(); | ||
assertThat(dt.get("index1", "test")).isNull(); | ||
assertThat(dt.get("index2", "test")).isNull(); | ||
} | ||
} |