/* *************************************************************************************** * Copyright (C) 2006 EsperTech, Inc. All rights reserved. * * http://www.espertech.com/esper * * http://www.espertech.com * * ---------------------------------------------------------------------------------- * * The software in this package is published under the terms of the GPL license * * a copy of which has been included with this distribution in the license.txt file. * *************************************************************************************** */ package com.espertech.esper.collection; import java.util.TreeMap; /** * Sorted, reference-counting set based on a TreeMap implementation that stores keys and a reference counter for * each unique key value. Each time the same key is added, the reference counter increases. * Each time a key is removed, the reference counter decreases. */ public class SortedRefCountedSet<K> { private TreeMap<K, Integer> refSet; private long countPoints; /** * Constructor. */ public SortedRefCountedSet() { refSet = new TreeMap<K, Integer>(); countPoints = 0; } /** * Clear out the collection. */ public void clear() { refSet.clear(); countPoints = 0; } /** * Add a key to the set. Add with a reference count of one if the key didn't exist in the set. * Increase the reference count by one if the key already exists. * * @param key to add */ public void add(K key) { Integer value = refSet.get(key); if (value == null) { refSet.put(key, 1); return; } value++; refSet.put(key, value); countPoints++; } /** * Add a key to the set with the given number of references. * * @param key to add * @param numReferences initial number of references */ public void add(K key, int numReferences) { Integer value = refSet.get(key); if (value == null) { refSet.put(key, numReferences); return; } throw new IllegalArgumentException("Key '" + key + "' already in collection"); } /** * Remove a key from the set. Removes the key if the reference count is one. * Decreases the reference count by one if the reference count is more then one. * * @param key to add * @throws IllegalStateException is a key is removed that wasn't added to the map */ public void remove(K key) { Integer value = refSet.get(key); if (value == null) { // This could happen if a sort operation gets a remove stream that duplicates events. // Generally points to an invalid combination of data windows. // throw new IllegalStateException("Attempting to remove key from map that wasn't added"); return; } countPoints--; if (value == 1) { refSet.remove(key); return; } value--; refSet.put(key, value); } /** * Returns the largest key value, or null if the collection is empty. * * @return largest key value, null if none */ public K maxValue() { if (refSet.isEmpty()) { return null; } return refSet.lastKey(); } /** * Returns the smallest key value, or null if the collection is empty. * * @return smallest key value, null if none */ public K minValue() { if (refSet.isEmpty()) { return null; } return refSet.firstKey(); } /** * Returns the number of data points. * * @return point count */ public long getCountPoints() { return countPoints; } public TreeMap<K, Integer> getRefSet() { return refSet; } public void setCountPoints(long countPoints) { this.countPoints = countPoints; } }