Class AbstractUnsizedContainer<T>

  • Type Parameters:
    T - the type of the Java objects that back each Item in the container
    All Implemented Interfaces:
    Container, Container.Indexed, Container.ItemSetChangeNotifier, Container.Ordered, Container.PropertySetChangeNotifier, Serializable, Connectable, PropertyExtractor<T>

    public abstract class AbstractUnsizedContainer<T>
    extends AbstractQueryContainer<T>
    A specialization of AbstractQueryContainer that doesn't require up-front knowledge of the underlying data's size.

    Subclasses only need support retrieving a contiguous window of fixed size from the underlying data via queryWindow(); when the requested window goes beyond the end of the underlying data, a short or empty result is returned. Based on just this information, this class maintains an estimate of the size of the underlying data. Each time that size estimate changes, handleSizeChange() is invoked to schedule a (non-reentrant) property set change notification. Once the end of the underlying data is reached, the size is known.

    If the actual size of the underlying data is constant, this class will eventually find it. If the actual size of the underlying data can change (either up or down), this class will adapt accordingly, but only when it learns of the new size through an invocation of queryWindow(); as this depends on how the container is used, this may not occur for a long time.

    When used to back a Vaadin table, the user will see a table that automatically grows as the user scrolls downward, until the actual end of the data is detected.

    See Also:
    AbstractQueryContainer, Serialized Form
    • Method Detail

      • query

        protected QueryList<T> query​(long hint)
        Description copied from class: AbstractQueryContainer
        Perform a query to (re)generate the list of Java objects backing this container.

        The particular position in the list we are interested in is given as a hint by the hint parameter. That is, an invocation of QueryList.get(long)(hint) is likely immediately after this method returns and if so it must complete without throwing an exception, unless hint is out of range.

        The hint can be used to implement a highly scalable query list containing external objects (such as from a database) where only a small "window" of objects is actually kept in memory at any one time. Of course, implementations are also free to ignore hint. However, the returned QueryList must at least tolerate one invocation of get(hint) without throwing an exception when hint is less that the size() of the returned QueryList.

        Specified by:
        query in class AbstractQueryContainer<T>
        Parameters:
        hint - index of the list element we are interested in
        Returns:
        list of Java objects backing this container
      • getWindowSize

        public int getWindowSize()
        Get the window size configured at construction time.
        Returns:
        configured window size
      • getCurrentSizeEstimate

        public long getCurrentSizeEstimate()
        Get the current size estimate for the underlying data.
        Returns:
        current size estimate
      • getSmallerEstimate

        protected long getSmallerEstimate​(long upperBound)
        Handle the case where the underlying data's size has suddenly shrunk, so we need to estimate the new size. All we know is that the actual new size is upperBound or less. This method should guess at the new value and, when called repeatedly, should converge rapidly to zero.

        Note: this situation will not occur if the underlying data's size never decreases.

        The implementation in AbstractUnsizedContainer returns upperBound * 0.75.

        Parameters:
        upperBound - an upper bound on the size of the underlying data
        Returns:
        estimate of the actual size of the underlying data
      • getLargerEstimate

        protected long getLargerEstimate​(long lowerBound)
        Estimate the size of the underlying data given that lowerBound is a lower bound. This effectively determines how much data will appear to be "beyond" the current window.

        The implementation in AbstractUnsizedContainer returns lowerBound * 1.25.

        Parameters:
        lowerBound - a lower bound on the size of the underlying data
        Returns:
        estimate of the actual size of the underlying data
      • queryWindow

        protected abstract List<? extends T> queryWindow​(long offset,
                                                         int length)
        Query the underlying data for a window of items in the given range. This should return the "window" of underlying data items starting at offset offset and having at least length length, or else however many remain. If offset is greater than or equal to the size of the underlying data, an empty list should be returned.
        Parameters:
        offset - starting offset for window
        length - window size, always greater than zero
        Returns:
        list containing at least length items in the window starting at offset offset; or less than length items if offset + length is greater than the size of the underlying data
      • handleSizeChange

        protected abstract void handleSizeChange()
        Emit a property set change notification.

        Subclasses are required to implement this so that size changes are detected.

        Note: to avoid re-entrancy problems, this method should not send out any notifications itself; instead, it must schedule notifications to be delivered later (perhaps in a different thread).

        Overrides:
        handleSizeChange in class AbstractQueryContainer<T>