package anastore.util;

import java.util.SortedMap;
import java.util.TreeMap;

/**
 * A set of bounds that keeps track of its least element and can
 * notify a listener when the least element changes.
 */
public class BoundSet
{
    private final SortedMap<Long, Integer> _tsCounts =
        new TreeMap<Long, Integer>();
    private long _llb = -1;
    private final BoundChangeHandler _bch;

    public interface BoundChangeHandler
    {
        public void onLowerBoundChange(long lowerBound);
    }

    public BoundSet(BoundChangeHandler bch)
    {
        _bch = bch;
    }

    /**
     * Add a value to the set of bounds.  This must not be less than
     * the lower bound most recently reached on the set.  
     */
    public synchronized void add(long bound)
        throws IllegalArgumentException
    {
        if (bound < _llb)
            throw new IllegalArgumentException
                ("Cannot add " + bound + " to bound set, since "
                 + _llb + " is already the least element");

        Integer cur = _tsCounts.get(bound);
        if (cur == null)
            _tsCounts.put(bound, 1);
        else
            _tsCounts.put(bound, cur+1);
    }

    /**
     * 
     */
    public synchronized void remove(long bound)
        throws IllegalArgumentException
    {
        Integer cur = _tsCounts.get(bound);
        if (cur == null)
            throw new IllegalArgumentException
                ("Bound " + bound + " is not in the set");
        if (cur > 1) {
            _tsCounts.put(bound, cur-1);
            return;
        } else {
            _tsCounts.remove(bound);

            long lowest = _tsCounts.firstKey();
            if (lowest > bound) {
                _llb = lowest;
                _bch.onLowerBoundChange(lowest);
            }
        }
    }
}
