CachedStack.java
- package Hoot.Runtime.Values;
- import java.util.*;
- import static Hoot.Runtime.Functions.Utils.*;
- /**
- * Caches items on a thread scoped stack.
- * @param <T> item type
- *
- * @author nik <nikboyd@sonic.net>
- * @see "Copyright 2010,2021 Nikolas S Boyd."
- * @see "Permission is granted to copy this work provided this copyright statement is retained in all copies."
- */
- public class CachedStack<T extends Cacheable<T>> {
- private final ThreadLocal<Stack<T>> cache = new ThreadLocal<>();
- private Stack<T> cacheStack() { cache.set(new Stack<>()); return cache.get(); }
- public Stack<T> cachedStack() { return itemOr(() -> cacheStack(), cache.get()); }
- public T pop() { return hasItems() ? cachedStack().pop() : defaultItem(); }
- public T top() { return hasItems() ? cachedStack().peek() : defaultItem(); }
- public T popIfTop(T item) { if (hasTop(item)) cachedStack().pop(); return item; }
- public boolean hasTop(Cacheable item) { return hasOne(item) && hasItems() && top() == item; }
- public T push(T item) {
- if (hasNone(item) || item.isDefault()) return item;
- item.stackIndex(stackDepth()); cachedStack().push(item); return item; }
- public T priorItem(T item) {
- return (item.isBottom() || !item.onStack()) ?
- defaultItem() : cachedStack().get(item.prior()); }
- public boolean hasItems() { return 0 < stackDepth(); }
- public boolean isEmpty() { return stackDepth() < 1; }
- public int stackDepth() { return cachedStack().size(); }
- private T defaultItem = null;
- public T defaultItem() { return this.defaultItem; }
- public CachedStack defaultIfEmpty(T item) { this.defaultItem = item; return this; }
- } // CachedStack<T>