class TopNSet implements Serializable {
    
    private static final long serialVersionUID = 1L;

    protected int maxsize;
    protected ConcurrentMap<String, Long> set;
    protected volatile long smallestKnownValue;
    protected volatile String smallestKnownKey;
    protected volatile long largestKnownValue;
    protected volatile String largestKnownKey; 
    
    public TopNSet(int size){
        maxsize = size;
        set = CacheBuilder.newBuilder().concurrencyLevel(64).<String, Long>build().asMap();
    }
    
    /**
     * Update the given String key with a new total value, perhaps displacing
     * an existing top-valued entry, and updating the fields recording max/min
     * keys in any case. 
     * 
     * @param key String key to update
     * @param value long new total value (*not* increment/decrement)
     */
    public void update(String key, long value){<FILL_FUNCTION_BODY>}
    
    public String getLargest() {
        return largestKnownKey;
    }
    
    public String getSmallest() {
        return smallestKnownKey;
    }
    
    /**
     * After an operation invalidating the previous largest/smallest entry,
     * find the new largest/smallest. 
     */
    public synchronized void updateBounds(){
        // freshly determine 
        smallestKnownValue = Long.MAX_VALUE;
        largestKnownValue = Long.MIN_VALUE;
        for(String k : set.keySet()){
            long v = set.get(k);
            if(v<smallestKnownValue){
                smallestKnownValue = v;
                smallestKnownKey = k;
            }
            if(v>largestKnownValue){
                largestKnownValue = v;
                largestKnownKey = k;
            }
        }
    }
    
    /**
     * Make internal map available (for checkpoint/restore purposes). 
     * @return HashMap&lt;String,Long&gt;
     */
    public ConcurrentMap<String, Long> getTopSet() {
        return set;
    }
    
    public int size() {
        return set.size();
    }
    
    /**
     * Get descending ordered list of key,count Entries.
     * 
     * @return SortedSet of Entry&lt;key, count&gt; descending-frequency 
     */
    public SortedSet<Map.Entry<?, Long>> getEntriesDescending() {
        TreeSet<Map.Entry<?, Long>> sorted = Histotable.getEntryByFrequencySortedSet();
        sorted.addAll(getTopSet().entrySet());
        return sorted; 
    }
    
    public int getMaxSize() {
        return maxsize;
    }
    public void setMaxSize(int max) {
        maxsize = max; 
    }
}

        // handle easy cases without synchronization
        if(set.size()<maxsize) {
            // need to reach maxsize before any eviction
            set.put(key, value);
            updateBounds(); 
            return; 
        }
        if(value<smallestKnownValue && !set.containsKey(key)) {
            // not in the running for top-N
            return; 
        }
        set.put(key,value); 
        synchronized(this) {
            if(set.size() > maxsize) {
                set.remove(smallestKnownKey);
                updateBounds();
            } else if(value < smallestKnownValue 
                    || value > largestKnownValue 
                    || key.equals(smallestKnownKey)
                    || key.equals(largestKnownKey)) {
                updateBounds(); 
            }
        }
    
<no_super_class>