All Downloads are FREE. Search and download functionalities are using the official Maven repository.

info.unterrainer.commons.jreutils.collections.DataTable Maven / Gradle / Ivy

There is a newer version: 0.3.15
Show newest version
package info.unterrainer.commons.jreutils.collections;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;

import lombok.Getter;
import lombok.experimental.Accessors;

/**
 * A synchronized data-structure acting as a table. You may create indexes for
 * various columns and later on retrieve sets of index-keys or the indexed
 * values.
* You also may specify fragmenting indexes, that define an additional filter * that then is applied on inserting a value. The value will then only be added * to a specific index, if the filter is satisfied. This allows for * runtime-efficient table-fragmentation. */ @Accessors(fluent = true) public class DataTable { private Class clazz; private int maxEntries; @Getter private DataQueue queue; private HashMap> keySuppliers = new HashMap<>(); private HashMap> filters = new HashMap<>(); private HashMap> maps = new HashMap<>(); public DataTable(final Class clazz, final int maxEntries) { this.clazz = clazz; this.maxEntries = maxEntries; queue = new DataQueue<>(maxEntries); } public DataTable addIndex(final String name, final Function keySupplier) { return addIndex(name, keySupplier, null); } @SuppressWarnings("unchecked") public DataTable addIndex(final String name, final Function keySupplier, final Function filter) { keySuppliers.put(name, (Function) keySupplier); if (filter != null) filters.put(name, filter); maps.put(name, new DataMap(maxEntries)); return this; } /** * Retrieves, but does not remove, the head (first inserted element) of this * DataTable, or returns {@code null} if this DataTable is empty. * * @return the head of this DataTable, or {@code null} if this DataTable is * empty */ public synchronized T peek() { return queue.peek(); } /** * Retrieves and removes the head (first inserted element) of this DataTable, or * returns {@code null} if this DataTable is empty. * * @return the head of this queue, or {@code null} if this DataTable is empty */ public synchronized T poll() { T e = queue.poll(); for (String name : keySuppliers.keySet()) { Function func = keySuppliers.get(name); DataMap map = maps.get(name); map.remove(func.apply(e)); } return e; } /** * Gets an element by a specified index. * * @param the type of the key used by the given index * @param name the name of the index * @param key the key of the element to retrieve using the given index * @return the element to retrieve */ public synchronized T get(final String name, final K key) { return maps.get(name).get(key); } /** * Adds one or more elements to the DataTable. *

* The element then gets properly indexed and added to the given indexes.
* If there is a filter for an index, the element is only added to that index, * if the filter is satisfied. * * @param elements the elements to insert */ @SuppressWarnings("unchecked") public synchronized void add(final T... elements) { for (T element : elements) { queue.offer(element); for (Entry> entry : keySuppliers.entrySet()) { Function filter = filters.get(entry.getKey()); DataMap map = maps.get(entry.getKey()); if (filter == null || filter.apply(element)) { Object key = entry.getValue().apply(element); map.put(key, element); } } } } /** * Get a set of keys for a given index. * * @param the type of the key for the given index * @param name the name of the index to get the keys from * @return a set of keys */ @SuppressWarnings("unchecked") public synchronized Set keySet(final String name) { return (Set) maps.get(name).keySet(); } /** * Get a list of keys for a given index. * * @param the type of the key for the given index * @param name the name of the index to get the keys from * @return a list of keys */ @SuppressWarnings("unchecked") public synchronized List keyList(final String name) { List list = new ArrayList<>(); list.addAll((Set) maps.get(name).keySet()); return list; } public synchronized Collection 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 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 load(T[] backingArray) { if (backingArray == null) backingArray = (T[]) Array.newInstance(clazz, 0); queue = new DataQueue<>(maxEntries, backingArray); for (Entry> entry : keySuppliers.entrySet()) { DataMap map = new DataMap<>(maxEntries); maps.put(entry.getKey(), map); Function filter = filters.get(entry.getKey()); for (T s : backingArray) if (filter == null || filter.apply(s)) map.put(entry.getValue().apply(s), s); } return this; } /** * Gets a list of all the elements in this DataTable as an detached * offline-copy. * * @return the list */ public synchronized List toList() { return queue.getListClone(); } /** * Get a list of the elements in this DataTable, that are in the given index, as * an detached offline-copy. * * @param name the name of the index to get the elements from * @return the list */ public synchronized List toList(final String name) { List list = new ArrayList<>(); list.addAll(maps.get(name).values()); return list; } /** * Gets an array of all the elements in this DataTable as an detached * offline-copy. * * @return the array */ @SuppressWarnings("unchecked") public synchronized T[] toArray() { T[] zeroArray = (T[]) Array.newInstance(clazz, 0); return queue.getListClone().toArray(zeroArray); } /** * Get an array of the elements in this DataTable, that are in the given index, * as an detached offline-copy. * * @param name the name of the index to get the elements from * @return the array */ @SuppressWarnings("unchecked") public synchronized T[] toArray(final String name) { T[] zeroArray = (T[]) Array.newInstance(clazz, 0); return toList(name).toArray(zeroArray); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy