History.java
package com.github.mk23.jmxproxy.util;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* <p>Fixed size historical attribute value store.</p>
*
* Saves an object into a fixed size round robin store. Allows clients to retreive latest
* value, a subset of latest values, or the full stored history of values. When number
* of stored values exceeds the fixed size of the store, the oldest values are overwritten.
*
* @param <T> type of objects held in this History.
*
* @since 2015-05-11
* @author mk23
* @version 3.3.2
*/
public class History<T> {
private List<T> objects;
private int length;
private int pointer;
private boolean wrapped;
/**
* <p>Default constructor.</p>
*
* Initializes the {@link Object} store {@link List} to the given history size.
*
* @param length number of {@link Object} values to keep in history.
*/
public History(final int length) {
this.length = length;
pointer = -1;
objects = new ArrayList<T>(Collections.nCopies(length, (T) null));
}
/**
* <p>Adds a item to the store.</p>
*
* Adds a new item to the history store. If the number of items exceeds the size
* of the store, the oldest item is overwritten.
*
* @param item newest item to add to the store.
*/
public final void add(final T item) {
wrapped = ++pointer == length;
pointer = pointer % length;
objects.set(pointer, item);
}
/**
* <p>Gets the latest item from the history store.</p>
*
* Gets the latest single item from the history store.
*
* @return Latest item from the history store or null if empty.
*/
public final T getLast() {
return pointer < 0 ? null : objects.get(pointer % length);
}
/**
* <p>Gets the full item history from the store.</p>
*
* Gets the full item history from the store as a {@link List}.
*
* @return {@link List} of the full history. May be empty if history has no items.
*/
public final List<T> get() {
return get(length);
}
/**
* <p>Gets a limited item history from the store.</p>
*
* Gets a limited history from the store as a {@link List}, based
* on requested item count. If the specified count is less than 0 or greater than
* the number of entries, a full history is returned instead.
*
* @param limit number of items to retreive from the history store.
*
* @return {@link List} of the requested slice of history. May be empty if history has no items.
*/
public final List<T> get(final int limit) {
if (pointer < 0) {
return Collections.emptyList();
}
int head = pointer + length * Boolean.compare(wrapped, false);
int size = Math.min(limit > 0 ? limit : Integer.MAX_VALUE, Math.min(head + 1, length));
List<T> rval = new ArrayList<T>(size);
for (int i = 0; i < size; i++) {
rval.add(objects.get((head - i) % length));
}
return rval;
}
}