CachedStack.java

  1. package Hoot.Runtime.Values;

  2. import java.util.*;
  3. import static Hoot.Runtime.Functions.Utils.*;

  4. /**
  5.  * Caches items on a thread scoped stack.
  6.  * @param <T> item type
  7.  *
  8.  * @author nik <nikboyd@sonic.net>
  9.  * @see "Copyright 2010,2021 Nikolas S Boyd."
  10.  * @see "Permission is granted to copy this work provided this copyright statement is retained in all copies."
  11.  */
  12. public class CachedStack<T extends Cacheable<T>> {

  13.     private final ThreadLocal<Stack<T>> cache = new ThreadLocal<>();
  14.     private Stack<T> cacheStack() { cache.set(new Stack<>()); return cache.get(); }
  15.     public Stack<T> cachedStack() { return itemOr(() -> cacheStack(), cache.get()); }

  16.     public T pop() { return hasItems() ? cachedStack().pop() : defaultItem(); }
  17.     public T top() { return hasItems() ? cachedStack().peek() : defaultItem(); }
  18.     public T popIfTop(T item) { if (hasTop(item)) cachedStack().pop(); return item; }
  19.     public boolean hasTop(Cacheable item) { return hasOne(item) && hasItems() && top() == item; }

  20.     public T push(T item) {
  21.         if (hasNone(item) || item.isDefault()) return item;
  22.         item.stackIndex(stackDepth()); cachedStack().push(item); return item; }

  23.     public T priorItem(T item) {
  24.         return (item.isBottom() || !item.onStack()) ?
  25.             defaultItem() : cachedStack().get(item.prior()); }

  26.     public boolean hasItems() { return 0 < stackDepth(); }
  27.     public boolean isEmpty() { return stackDepth() < 1; }
  28.     public int stackDepth() { return cachedStack().size(); }

  29.     private T defaultItem = null;
  30.     public T defaultItem() { return this.defaultItem; }
  31.     public CachedStack defaultIfEmpty(T item) { this.defaultItem = item; return this; }

  32. } // CachedStack<T>