//# 0 errors, 182 messages
//#
/*
    //#LRUCacheImpl.java:1:1: class: org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap
    //#LRUCacheImpl.java:1:1: method: org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap.org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap__static_init
    //#LRUCacheImpl.java:1:1: class: org.apache.roller.weblogger.util.cache.LRUCacheImpl
 * Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  The ASF licenses this file to You
 * under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.  For additional information regarding
 * copyright in this work, please see the NOTICE file in the top level
 * directory of this distribution.
 */

package org.apache.roller.weblogger.util.cache;

import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 * A simple LRU Cache.
 */
public class LRUCacheImpl implements Cache {
    
    private static Log log = LogFactory.getLog(LRUCacheImpl.class);
    //#LRUCacheImpl.java:35: method: org.apache.roller.weblogger.util.cache.LRUCacheImpl.org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init
    //#LRUCacheImpl.java:35: Warning: method not available
    //#    -- call on Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.cache.LRUCacheImpl
    //#    method: org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init
    //#    unanalyzed callee: Log org.apache.commons.logging.LogFactory:getLog(Class)
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Descendant_Table[org/apache/roller/weblogger/util/cache/LRUCacheImpl]
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.clear()V
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.get(Ljava/lang/String;)Ljava/lang/Object;
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.getId()Ljava/lang/String;
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.getStats()Ljava/util/Map;
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.put(Ljava/lang/String;Ljava/lang/Object;)V
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.remove(Ljava/lang/String;)V
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): log
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): org/apache/roller/weblogger/util/cache/Cache.__Descendant_Table[org/apache/roller/weblogger/util/cache/LRUCacheImpl]
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Descendant_Table[org/apache/roller/weblogger/util/cache/LRUCacheImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): org/apache/roller/weblogger/util/cache/Cache.__Descendant_Table[org/apache/roller/weblogger/util/cache/LRUCacheImpl] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.clear()V == &clear
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.get(Ljava/lang/String;)Ljava/lang/Object; == &get
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.getId()Ljava/lang/String; == &getId
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.getStats()Ljava/util/Map; == &getStats
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.put(Ljava/lang/String;Ljava/lang/Object;)V == &put
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): __Dispatch_Table.remove(Ljava/lang/String;)V == &remove
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init): init'ed(log)
    //#LRUCacheImpl.java:35: end of method: org.apache.roller.weblogger.util.cache.LRUCacheImpl.org.apache.roller.weblogger.util.cache.LRUCacheImpl__static_init
    
    private String id = null;
    private Map cache = null;
    
    // for metrics
    protected double hits = 0;
    protected double misses = 0;
    protected double puts = 0;
    protected double removes = 0;
    protected Date startTime = new Date();
    
    
    protected LRUCacheImpl(String id) {
    //#LRUCacheImpl.java:48: method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): id
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): new Date(LRUCacheImpl#1) num objects
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.cache
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.hits
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.id
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.misses
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.puts
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.removes
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.startTime
    //#new obj(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): new Date(LRUCacheImpl#1)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): init'ed(this.cache)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.hits == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.misses == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.puts == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.removes == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.id == id
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): init'ed(this.id)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): this.startTime == &new Date(LRUCacheImpl#1)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): new Date(LRUCacheImpl#1) num objects == 1
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)): Effects-of-calling:java.util.LinkedHashMap
        
        this.id = id;
        this.cache = Collections.synchronizedMap(new LRULinkedHashMap(100));
    }
    //#LRUCacheImpl.java:52: end of method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.org.apache.roller.weblogger.util.cache.LRUCacheImpl(String)
    
    
    protected LRUCacheImpl(String id, int maxsize) {
    //#LRUCacheImpl.java:55: method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): id
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): maxsize
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): new Date(LRUCacheImpl#1) num objects
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.cache
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.hits
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.id
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.misses
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.puts
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.removes
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.startTime
    //#new obj(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): new Date(LRUCacheImpl#1)
    //#pre[2] (void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): maxsize in -1_610_612_737..3_221_225_471
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): init'ed(this.cache)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.hits == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.misses == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.puts == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.removes == +0
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.id == id
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): init'ed(this.id)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): this.startTime == &new Date(LRUCacheImpl#1)
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): new Date(LRUCacheImpl#1) num objects == 1
    //#unanalyzed(void org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)): Effects-of-calling:java.util.LinkedHashMap
        
        this.id = id;
        this.cache = Collections.synchronizedMap(new LRULinkedHashMap(maxsize));
    }
    //#LRUCacheImpl.java:59: end of method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.org.apache.roller.weblogger.util.cache.LRUCacheImpl(String, int)
    
    
    public String getId() {
        return this.id;
    //#LRUCacheImpl.java:63: method: String org.apache.roller.weblogger.util.cache.LRUCacheImpl.getId()
    //#input(String getId()): this
    //#input(String getId()): this.id
    //#output(String getId()): return_value
    //#pre[2] (String getId()): init'ed(this.id)
    //#post(String getId()): return_value == this.id
    //#post(String getId()): init'ed(return_value)
    //#LRUCacheImpl.java:63: end of method: String org.apache.roller.weblogger.util.cache.LRUCacheImpl.getId()
    }
    
    
    /**
     * Store an entry in the cache.
     */
    public synchronized void put(String key, Object value) {
        
        this.cache.put(key, value);
    //#LRUCacheImpl.java:72: method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.put(String, Object)
    //#input(void put(String, Object)): key
    //#input(void put(String, Object)): this
    //#input(void put(String, Object)): this.cache
    //#input(void put(String, Object)): this.puts
    //#input(void put(String, Object)): value
    //#output(void put(String, Object)): this.puts
    //#pre[2] (void put(String, Object)): init'ed(this.puts)
    //#pre[4] (void put(String, Object)): this.cache != null
    //#post(void put(String, Object)): this.puts == old this.puts + 1
    //#post(void put(String, Object)): init'ed(this.puts)
        puts++;
    }
    //#LRUCacheImpl.java:74: end of method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.put(String, Object)
    
    
    /**
     * Retrieve an entry from the cache.
     */
    public synchronized Object get(String key) {
        
        Object obj = this.cache.get(key);
    //#LRUCacheImpl.java:82: method: Object org.apache.roller.weblogger.util.cache.LRUCacheImpl.get(String)
    //#input(Object get(String)): key
    //#input(Object get(String)): this
    //#input(Object get(String)): this.cache
    //#input(Object get(String)): this.hits
    //#input(Object get(String)): this.misses
    //#output(Object get(String)): return_value
    //#output(Object get(String)): this.hits
    //#output(Object get(String)): this.misses
    //#pre[5] (Object get(String)): this.cache != null
    //#pre[2] (Object get(String)): (soft) init'ed(this.hits)
    //#pre[3] (Object get(String)): (soft) init'ed(this.misses)
    //#post(Object get(String)): init'ed(return_value)
    //#post(Object get(String)): this.hits == One-of{old this.hits, old this.hits + 1}
    //#post(Object get(String)): (soft) init'ed(this.hits)
    //#post(Object get(String)): this.misses == One-of{old this.misses + 1, old this.misses}
    //#post(Object get(String)): (soft) init'ed(this.misses)
    //#test_vector(Object get(String)): java.util.Map:get(...)@82: Inverse{null}, Addr_Set{null}
        
        // for metrics
        if(obj == null) {
            misses++;
        } else {
            hits++;
        }
        
        return obj;
    //#LRUCacheImpl.java:91: end of method: Object org.apache.roller.weblogger.util.cache.LRUCacheImpl.get(String)
    }
    
    
    public synchronized void remove(String key) {
        
        this.cache.remove(key);
    //#LRUCacheImpl.java:97: method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.remove(String)
    //#input(void remove(String)): key
    //#input(void remove(String)): this
    //#input(void remove(String)): this.cache
    //#input(void remove(String)): this.removes
    //#output(void remove(String)): this.removes
    //#pre[2] (void remove(String)): init'ed(this.removes)
    //#pre[4] (void remove(String)): this.cache != null
    //#post(void remove(String)): this.removes == old this.removes + 1
    //#post(void remove(String)): init'ed(this.removes)
        removes++;
    }
    //#LRUCacheImpl.java:99: end of method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.remove(String)
    
    
    public synchronized void clear() {
        
        this.cache.clear();
    //#LRUCacheImpl.java:104: method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.clear()
    //#input(void clear()): this
    //#input(void clear()): this.cache
    //#output(void clear()): new Date(clear#1) num objects
    //#output(void clear()): this.hits
    //#output(void clear()): this.misses
    //#output(void clear()): this.puts
    //#output(void clear()): this.removes
    //#output(void clear()): this.startTime
    //#new obj(void clear()): new Date(clear#1)
    //#pre[2] (void clear()): this.cache != null
    //#post(void clear()): this.hits == +0
    //#post(void clear()): this.misses == +0
    //#post(void clear()): this.puts == +0
    //#post(void clear()): this.removes == +0
    //#post(void clear()): this.startTime == &new Date(clear#1)
    //#post(void clear()): new Date(clear#1) num objects == 1
        
        // clear metrics
        hits = 0;
        misses = 0;
        puts = 0;
        removes = 0;
        startTime = new Date();
    }
    //#LRUCacheImpl.java:112: end of method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl.clear()
    
    
    public Map getStats() {
        
        Map stats = new HashMap();
    //#LRUCacheImpl.java:117: method: Map org.apache.roller.weblogger.util.cache.LRUCacheImpl.getStats()
    //#input(Map getStats()): this
    //#input(Map getStats()): this.hits
    //#input(Map getStats()): this.misses
    //#input(Map getStats()): this.puts
    //#input(Map getStats()): this.removes
    //#input(Map getStats()): this.startTime
    //#output(Map getStats()): new HashMap(getStats#1) num objects
    //#output(Map getStats()): return_value
    //#new obj(Map getStats()): new HashMap(getStats#1)
    //#pre[2] (Map getStats()): init'ed(this.hits)
    //#pre[5] (Map getStats()): init'ed(this.misses)
    //#pre[6] (Map getStats()): init'ed(this.puts)
    //#pre[7] (Map getStats()): init'ed(this.removes)
    //#pre[9] (Map getStats()): init'ed(this.startTime)
    //#pre[3] (Map getStats()): (soft) this.hits + this.misses != +0
    //#post(Map getStats()): return_value == &new HashMap(getStats#1)
    //#post(Map getStats()): new HashMap(getStats#1) num objects == 1
        stats.put("startTime", this.startTime);
        stats.put("hits", new Double(this.hits));
        stats.put("misses", new Double(this.misses));
        stats.put("puts", new Double(this.puts));
        stats.put("removes", new Double(this.removes));
        
        // calculate efficiency
        if((misses - removes) > 0) {
            double efficiency = hits / (misses + hits);
            stats.put("efficiency", new Double(efficiency * 100));
        }
        
        return stats;
    //#LRUCacheImpl.java:130: end of method: Map org.apache.roller.weblogger.util.cache.LRUCacheImpl.getStats()
    }
    
    
    // David Flanaghan: http://www.davidflanagan.com/blog/000014.html
    private static class LRULinkedHashMap extends LinkedHashMap {
        protected int maxsize;
        
        public LRULinkedHashMap(int maxsize) {
            super(maxsize * 4 / 3 + 1, 0.75f, true);
    //#LRUCacheImpl.java:139: method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap.org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)): maxsize
    //#input(void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)): this
    //#output(void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)): this.maxsize
    //#pre[2] (void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)): maxsize in -1_610_612_737..3_221_225_471
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)): this.maxsize == maxsize
    //#post(void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)): this.maxsize in -1_610_612_737..3_221_225_471
            this.maxsize = maxsize;
        }
    //#LRUCacheImpl.java:141: end of method: void org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap.org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap(int)
        
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return this.size() > this.maxsize;
    //#LRUCacheImpl.java:144: method: bool org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap.removeEldestEntry(Map$Entry)
    //#LRUCacheImpl.java:144: Warning: method not available
    //#    -- call on int org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap:size()
    //#    severity: INFORMATIONAL
    //#    class: org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap
    //#    method: bool removeEldestEntry(Map$Entry)
    //#    unanalyzed callee: int org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap:size()
    //#input(bool removeEldestEntry(Map$Entry)): this
    //#input(bool removeEldestEntry(Map$Entry)): this.maxsize
    //#output(bool removeEldestEntry(Map$Entry)): return_value
    //#pre[2] (bool removeEldestEntry(Map$Entry)): init'ed(this.maxsize)
    //#post(bool removeEldestEntry(Map$Entry)): init'ed(return_value)
    //#LRUCacheImpl.java:144: end of method: bool org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap.removeEldestEntry(Map$Entry)
        }
    }
    
}
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap__static_init): __Descendant_Table[org/apache/roller/weblogger/util/cache/LRUCacheImpl$LRULinkedHashMap]
    //#output(org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap__static_init): __Dispatch_Table.removeEldestEntry(Ljava/util/Map$Entry;)Z
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap__static_init): __Descendant_Table[org/apache/roller/weblogger/util/cache/LRUCacheImpl$LRULinkedHashMap] == &__Dispatch_Table
    //#post(org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap__static_init): __Dispatch_Table.removeEldestEntry(Ljava/util/Map$Entry;)Z == &removeEldestEntry
    //#LRUCacheImpl.java:: end of method: org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap.org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap__static_init
    //#LRUCacheImpl.java:: end of class: org.apache.roller.weblogger.util.cache.LRUCacheImpl$LRULinkedHashMap
    //#LRUCacheImpl.java:: end of class: org.apache.roller.weblogger.util.cache.LRUCacheImpl
