View Javadoc
1   package org.apache.commons.jcs3.engine.memory.lru;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import junit.framework.TestCase;
23  
24  import java.util.HashSet;
25  import java.util.Map;
26  import java.util.Set;
27  
28  import org.apache.commons.jcs3.JCS;
29  import org.apache.commons.jcs3.access.CacheAccess;
30  import org.apache.commons.jcs3.access.exception.CacheException;
31  import org.apache.commons.jcs3.engine.CacheElement;
32  import org.apache.commons.jcs3.engine.behavior.ICacheElement;
33  import org.apache.commons.jcs3.engine.control.CompositeCache;
34  import org.apache.commons.jcs3.engine.control.CompositeCacheManager;
35  
36  /**
37   * Tests for the test LHMLRU implementation.
38   */
39  public class LHMLRUMemoryCacheUnitTest
40      extends TestCase
41  {
42      /** Test setup */
43      @Override
44      public void setUp()
45      {
46          JCS.setConfigFilename( "/TestLHMLRUCache.ccf" );
47      }
48  
49      /**
50       * Verify that the mru gets used by a non-defined region when it is set as the default in the
51       * default region.
52       * <p>
53       * @throws CacheException
54       */
55      public void testLoadFromCCF()
56          throws CacheException
57      {
58          final CacheAccess<String, String> cache = JCS.getInstance( "testLoadFromCCF" );
59          final String memoryCacheName = cache.getCacheAttributes().getMemoryCacheName();
60          assertTrue( "Cache name should have LHMLRU in it.", memoryCacheName.indexOf( "LHMLRUMemoryCache" ) != -1 );
61      }
62  
63      /**
64       * put twice as many as the max.  verify that the second half is in the cache.
65       * <p>
66       * @throws CacheException
67       */
68      public void testPutGetThroughHub()
69          throws CacheException
70      {
71          final CacheAccess<String, String> cache = JCS.getInstance( "testPutGetThroughHub" );
72  
73          final int max = cache.getCacheAttributes().getMaxObjects();
74          final int items = max * 2;
75  
76          for ( int i = 0; i < items; i++ )
77          {
78              cache.put( i + ":key", "myregion" + " data " + i );
79          }
80  
81          // Test that first items are not in the cache
82          for ( int i = max -1; i >= 0; i-- )
83          {
84              final String value = cache.get( i + ":key" );
85              assertNull( "Should not have value for key [" + i + ":key" + "] in the cache." + cache.getStats(), value );
86          }
87  
88          // Test that last items are in cache
89          // skip 2 for the buffer.
90          for ( int i = max + 2; i < items; i++ )
91          {
92              final String value = cache.get( i + ":key" );
93              assertEquals( "myregion" + " data " + i, value );
94          }
95  
96          // Test that getMultiple returns all the items remaining in cache and none of the missing ones
97          final Set<String> keys = new HashSet<>();
98          for ( int i = 0; i < items; i++ )
99          {
100             keys.add( i + ":key" );
101         }
102 
103         final Map<String, ICacheElement<String, String>> elements = cache.getCacheElements( keys );
104         for ( int i = max-1; i >= 0; i-- )
105         {
106             assertNull( "Should not have value for key [" + i + ":key" + "] in the cache." + cache.getStats(), elements.get( i + ":key" ) );
107         }
108         for ( int i = max + 2; i < items; i++ )
109         {
110             final ICacheElement<String, String> element = elements.get( i + ":key" );
111             assertNotNull( "element " + i + ":key is missing", element );
112             assertEquals( "value " + i + ":key", "myregion" + " data " + i, element.getVal() );
113         }
114     }
115 
116     /**
117      * Put twice as many as the max, twice. verify that the second half is in the cache.
118      * <p>
119      * @throws CacheException
120      */
121     public void testPutGetThroughHubTwice()
122         throws CacheException
123     {
124         final CacheAccess<String, String> cache = JCS.getInstance( "testPutGetThroughHubTwice" );
125 
126         final int max = cache.getCacheAttributes().getMaxObjects();
127         final int items = max * 2;
128 
129         for ( int i = 0; i < items; i++ )
130         {
131             cache.put( i + ":key", "myregion" + " data " + i );
132         }
133 
134         for ( int i = 0; i < items; i++ )
135         {
136             cache.put( i + ":key", "myregion" + " data " + i );
137         }
138 
139         // Test that first items are not in the cache
140         for ( int i = max -1; i >= 0; i-- )
141         {
142             final String value = cache.get( i + ":key" );
143             assertNull( "Should not have value for key [" + i + ":key" + "] in the cache.", value );
144         }
145 
146         // Test that last items are in cache
147         // skip 2 for the buffer.
148         for ( int i = max + 2; i < items; i++ )
149         {
150             final String value = cache.get( i + ":key" );
151             assertEquals( "myregion" + " data " + i, value );
152         }
153 
154     }
155 
156     /**
157      * put the max and remove each. verify that they are all null.
158      * <p>
159      * @throws CacheException
160      */
161     public void testPutRemoveThroughHub()
162         throws CacheException
163     {
164         final CacheAccess<String, String> cache = JCS.getInstance( "testPutRemoveThroughHub" );
165 
166         final int max = cache.getCacheAttributes().getMaxObjects();
167         final int items = max * 2;
168 
169         for ( int i = 0; i < items; i++ )
170         {
171             cache.put( i + ":key", "myregion" + " data " + i );
172         }
173 
174         for ( int i = 0; i < items; i++ )
175         {
176             cache.remove( i + ":key" );
177         }
178 
179         // Test that first items are not in the cache
180         for ( int i = max; i >= 0; i-- )
181         {
182             final String value = cache.get( i + ":key" );
183             assertNull( "Should not have value for key [" + i + ":key" + "] in the cache.", value );
184         }
185     }
186 
187     /**
188      * put the max and clear. verify that no elements remain.
189      * <p>
190      * @throws CacheException
191      */
192     public void testClearThroughHub()
193         throws CacheException
194     {
195         final CacheAccess<String, String> cache = JCS.getInstance( "testClearThroughHub" );
196 
197         final int max = cache.getCacheAttributes().getMaxObjects();
198         final int items = max * 2;
199 
200         for ( int i = 0; i < items; i++ )
201         {
202             cache.put( i + ":key", "myregion" + " data " + i );
203         }
204 
205         cache.clear();
206 
207         // Test that first items are not in the cache
208         for ( int i = max; i >= 0; i-- )
209         {
210             final String value = cache.get( i + ":key" );
211             assertNull( "Should not have value for key [" + i + ":key" + "] in the cache.", value );
212         }
213     }
214 
215     /**
216      * Get stats.
217      * <p>
218      * @throws CacheException
219      */
220     public void testGetStatsThroughHub()
221         throws CacheException
222     {
223         final CacheAccess<String, String> cache = JCS.getInstance( "testGetStatsThroughHub" );
224 
225         final int max = cache.getCacheAttributes().getMaxObjects();
226         final int items = max * 2;
227 
228         for ( int i = 0; i < items; i++ )
229         {
230             cache.put( i + ":key", "myregion" + " data " + i );
231         }
232 
233         final String stats = cache.getStats();
234 
235         //System.out.println( stats );
236 
237         // TODO improve stats check
238         assertTrue( "Should have 200 puts" + stats, stats.indexOf( "200" ) != -1 );
239     }
240 
241     /**
242      * Put half the max and clear. get the key array and verify that it has the correct number of
243      * items.
244      * <p>
245      * @throws Exception
246      */
247     public void testGetKeyArray()
248         throws Exception
249     {
250         final CompositeCacheManager cacheMgr = CompositeCacheManager.getUnconfiguredInstance();
251         cacheMgr.configure( "/TestLHMLRUCache.ccf" );
252         final CompositeCache<String, String> cache = cacheMgr.getCache( "testGetKeyArray" );
253 
254         final LHMLRUMemoryCache<String, String> mru = new LHMLRUMemoryCache<>();
255         mru.initialize( cache );
256 
257         final int max = cache.getCacheAttributes().getMaxObjects();
258         final int items = max / 2;
259 
260         for ( int i = 0; i < items; i++ )
261         {
262             final ICacheElement<String, String> ice = new CacheElement<>( cache.getCacheName(), i + ":key", cache.getCacheName() + " data " + i );
263             ice.setElementAttributes( cache.getElementAttributes() );
264             mru.update( ice );
265         }
266 
267         final Set<String> keys = mru.getKeySet();
268 
269         assertEquals( "Wrong number of keys.", items, keys.size() );
270     }
271 
272     /**
273      * Add a few keys with the delimiter. Remove them.
274      * <p>
275      * @throws CacheException
276      */
277     public void testRemovePartialThroughHub()
278         throws CacheException
279     {
280         final CacheAccess<String, String> cache = JCS.getInstance( "testRemovePartialThroughHub" );
281 
282         final int max = cache.getCacheAttributes().getMaxObjects();
283         final int items = max / 2;
284 
285         cache.put( "test", "data" );
286 
287         final String root = "myroot";
288 
289         for ( int i = 0; i < items; i++ )
290         {
291             cache.put( root + ":" + i + ":key", "myregion" + " data " + i );
292         }
293 
294         // Test that last items are in cache
295         for ( int i = 0; i < items; i++ )
296         {
297             final String value = cache.get( root + ":" + i + ":key" );
298             assertEquals( "myregion" + " data " + i, value );
299         }
300 
301         // remove partial
302         cache.remove( root + ":" );
303 
304         for ( int i = 0; i < items; i++ )
305         {
306             assertNull( "Should have been removed by partial loop.", cache.get( root + ":" + i + ":key" ) );
307         }
308 
309         assertNotNull( "Other item should be in the cache.", cache.get( "test" ) );
310     }
311 }