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.fifo;
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 * FIFO (first in, first out) cache controller implementation.
30 */
31 public class FifoCacheController 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 FifoCacheController() {
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 return cache.get(key);
121 }
122
123 public Object removeObject(CacheModel cacheModel, Object key) {
124 keyList.remove(key);
125 return cache.remove(key);
126 }
127
128 /**
129 * Flushes the cache.
130 *
131 * @param cacheModel
132 * The cache model
133 */
134 public void flush(CacheModel cacheModel) {
135 cache.clear();
136 keyList.clear();
137 }
138
139 }