View Javadoc
1   /*
2    * Copyright 2004-2022 the original author or authors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *    https://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package com.ibatis.sqlmap.engine.cache.lru;
17  
18  import com.ibatis.sqlmap.engine.cache.CacheController;
19  import com.ibatis.sqlmap.engine.cache.CacheModel;
20  
21  import java.util.Collections;
22  import java.util.HashMap;
23  import java.util.LinkedList;
24  import java.util.List;
25  import java.util.Map;
26  import java.util.Properties;
27  
28  /**
29   * LRU (least recently used) cache controller implementation.
30   */
31  public class LruCacheController implements CacheController {
32  
33    /** The cache size. */
34    private int cacheSize;
35  
36    /** The cache. */
37    private Map cache;
38  
39    /** The key list. */
40    private List keyList;
41  
42    /**
43     * Default constructor.
44     */
45    public LruCacheController() {
46      this.cacheSize = 100;
47      this.cache = Collections.synchronizedMap(new HashMap());
48      this.keyList = Collections.synchronizedList(new LinkedList());
49    }
50  
51    /**
52     * Gets the cache size.
53     *
54     * @return the cache size
55     */
56    public int getCacheSize() {
57      return cacheSize;
58    }
59  
60    /**
61     * Sets the cache size.
62     *
63     * @param cacheSize
64     *          the new cache size
65     */
66    public void setCacheSize(int cacheSize) {
67      this.cacheSize = cacheSize;
68    }
69  
70    /**
71     * Configures the cache
72     *
73     * @param props
74     *          Optionally can contain properties [reference-type=WEAK|SOFT|STRONG]
75     */
76    public void setProperties(Properties props) {
77      String size = props.getProperty("cache-size");
78      if (size == null) {
79        size = props.getProperty("size");
80      }
81      if (size != null) {
82        cacheSize = Integer.parseInt(size);
83      }
84    }
85  
86    /**
87     * Add an object to the cache
88     *
89     * @param cacheModel
90     *          The cacheModel
91     * @param key
92     *          The key of the object to be cached
93     * @param value
94     *          The object to be cached
95     */
96    public void putObject(CacheModel cacheModel, Object key, Object value) {
97      cache.put(key, value);
98      keyList.add(key);
99      if (keyList.size() > cacheSize) {
100       try {
101         Object oldestKey = keyList.remove(0);
102         cache.remove(oldestKey);
103       } catch (IndexOutOfBoundsException e) {
104         // ignore
105       }
106     }
107   }
108 
109   /**
110    * Get an object out of the cache.
111    *
112    * @param cacheModel
113    *          The cache model
114    * @param key
115    *          The key of the object to be returned
116    *
117    * @return The cached object (or null)
118    */
119   public Object getObject(CacheModel cacheModel, Object key) {
120     Object result = cache.get(key);
121     keyList.remove(key);
122     if (result != null) {
123       keyList.add(key);
124     }
125     return result;
126   }
127 
128   public Object removeObject(CacheModel cacheModel, Object key) {
129     keyList.remove(key);
130     return cache.remove(key);
131   }
132 
133   /**
134    * Flushes the cache.
135    *
136    * @param cacheModel
137    *          The cache model
138    */
139   public void flush(CacheModel cacheModel) {
140     cache.clear();
141     keyList.clear();
142   }
143 
144 }