Merge "Switch ReferenceWithHistory to use ArrayDeque" into rvc-dev
This commit is contained in:
@@ -22,7 +22,7 @@ import android.annotation.Nullable;
|
|||||||
|
|
||||||
import com.android.internal.util.IndentingPrintWriter;
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.ArrayDeque;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class that behaves like the following definition, except it stores the history of values set
|
* A class that behaves like the following definition, except it stores the history of values set
|
||||||
@@ -50,11 +50,18 @@ import java.util.LinkedList;
|
|||||||
*/
|
*/
|
||||||
public final class ReferenceWithHistory<V> {
|
public final class ReferenceWithHistory<V> {
|
||||||
|
|
||||||
/** The size the history linked list is allowed to grow to. */
|
private static final Object NULL_MARKER = "{null marker}";
|
||||||
|
|
||||||
|
/** The maximum number of references to store. */
|
||||||
private final int mMaxHistorySize;
|
private final int mMaxHistorySize;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The history storage. Note that ArrayDeque doesn't support {@code null} so this stores Object
|
||||||
|
* and not V. Use {@link #packNullIfRequired(Object)} and {@link #unpackNullIfRequired(Object)}
|
||||||
|
* to convert to / from the storage object.
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private LinkedList<V> mValues;
|
private ArrayDeque<Object> mValues;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an instance that records, at most, the specified number of values.
|
* Creates an instance that records, at most, the specified number of values.
|
||||||
@@ -69,22 +76,31 @@ public final class ReferenceWithHistory<V> {
|
|||||||
/** Returns the current value, or {@code null} if it has never been set. */
|
/** Returns the current value, or {@code null} if it has never been set. */
|
||||||
@Nullable
|
@Nullable
|
||||||
public V get() {
|
public V get() {
|
||||||
return (mValues == null || mValues.isEmpty()) ? null : mValues.getFirst();
|
if (mValues == null || mValues.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Object value = mValues.getFirst();
|
||||||
|
return unpackNullIfRequired(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Sets the current value. Returns the previous value, or {@code null}. */
|
/**
|
||||||
|
* Sets the current value. Returns the previous value, which can be {@code null} if the
|
||||||
|
* reference has never been set, or if the reference has been set to {@code null}.
|
||||||
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public V set(@Nullable V newValue) {
|
public V set(@Nullable V newValue) {
|
||||||
if (mValues == null) {
|
if (mValues == null) {
|
||||||
mValues = new LinkedList<>();
|
mValues = new ArrayDeque<>(mMaxHistorySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mValues.size() >= mMaxHistorySize) {
|
||||||
|
mValues.removeLast();
|
||||||
}
|
}
|
||||||
|
|
||||||
V previous = get();
|
V previous = get();
|
||||||
|
|
||||||
mValues.addFirst(newValue);
|
Object nullSafeValue = packNullIfRequired(newValue);
|
||||||
if (mValues.size() > mMaxHistorySize) {
|
mValues.addFirst(nullSafeValue);
|
||||||
mValues.removeLast();
|
|
||||||
}
|
|
||||||
return previous;
|
return previous;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,8 +112,8 @@ public final class ReferenceWithHistory<V> {
|
|||||||
ipw.println("{Empty}");
|
ipw.println("{Empty}");
|
||||||
} else {
|
} else {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (V value : mValues) {
|
for (Object value : mValues) {
|
||||||
ipw.println(i + ": " + value);
|
ipw.println(i + ": " + unpackNullIfRequired(value));
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,4 +131,23 @@ public final class ReferenceWithHistory<V> {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return String.valueOf(get());
|
return String.valueOf(get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns a non-nullable Object into a nullable value. See also
|
||||||
|
* {@link #packNullIfRequired(Object)}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Nullable
|
||||||
|
private V unpackNullIfRequired(@NonNull Object value) {
|
||||||
|
return value == NULL_MARKER ? null : (V) value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Turns a nullable value into a non-nullable Object. See also
|
||||||
|
* {@link #unpackNullIfRequired(Object)}.
|
||||||
|
*/
|
||||||
|
@NonNull
|
||||||
|
private Object packNullIfRequired(@Nullable V value) {
|
||||||
|
return value == null ? NULL_MARKER : value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user