View Javadoc
1   package org.apache.commons.jcs.utils.struct;
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.Test;
23  import junit.framework.TestCase;
24  import junit.framework.TestSuite;
25  
26  import java.util.Iterator;
27  
28  /**
29   * Tests the LRUMap
30   *
31   */
32  public class LRUMapConcurrentUnitTest
33      extends TestCase
34  {
35      /** number to test with */
36      private static int items = 20000;
37  
38      /**
39       * Constructor for the TestSimpleLoad object
40       * <p>
41       * @param testName
42       *            Description of the Parameter
43       */
44      public LRUMapConcurrentUnitTest( String testName )
45      {
46          super( testName );
47      }
48  
49      /**
50       * A unit test suite for JUnit
51       * <p>
52       * @return The test suite
53       */
54      public static Test suite()
55      {
56          // run the basic tests
57          TestSuite suite = new TestSuite( LRUMapConcurrentUnitTest.class );
58  
59          // run concurrent tests
60          final LRUMap<String, String> map = new LRUMap<String, String>( 2000 );
61          suite.addTest( new LRUMapConcurrentUnitTest( "conc1" )
62          {
63              @Override
64              public void runTest()
65                  throws Exception
66              {
67                  this.runConcurrentPutGetTests( map, 2000 );
68              }
69          } );
70          suite.addTest( new LRUMapConcurrentUnitTest( "conc2" )
71          {
72              @Override
73              public void runTest()
74                  throws Exception
75              {
76                  this.runConcurrentPutGetTests( map, 2000 );
77              }
78          } );
79          suite.addTest( new LRUMapConcurrentUnitTest( "conc3" )
80          {
81              @Override
82              public void runTest()
83                  throws Exception
84              {
85                  this.runConcurrentPutGetTests( map, 2000 );
86              }
87          } );
88  
89          // run more concurrent tests
90          final int max2 = 20000;
91          final LRUMap<String, String> map2 = new LRUMap<String, String>( max2 );
92          suite.addTest( new LRUMapConcurrentUnitTest( "concB1" )
93          {
94              @Override
95              public void runTest()
96                  throws Exception
97              {
98                  this.runConcurrentRangeTests( map2, 10000, max2 );
99              }
100         } );
101         suite.addTest( new LRUMapConcurrentUnitTest( "concB1" )
102         {
103             @Override
104             public void runTest()
105                 throws Exception
106             {
107                 this.runConcurrentRangeTests( map2, 0, 9999 );
108             }
109         } );
110 
111         return suite;
112     }
113 
114     /**
115      * Just test that we can put, get and remove as expected.
116      * <p>
117      * @throws Exception
118      *                Description of the Exception
119      */
120     public void testSimpleLoad()
121         throws Exception
122     {
123         LRUMap<String, String> map = new LRUMap<String, String>( items );
124 
125         for ( int i = 0; i < items; i++ )
126         {
127             map.put( i + ":key", "data" + i );
128         }
129 
130         for ( int i = items - 1; i >= 0; i-- )
131         {
132             String res = map.get( i + ":key" );
133             assertNotNull( "[" + i + ":key] should not be null", res );
134         }
135 
136         // test removal
137         map.remove( "300:key" );
138         assertNull( map.get( "300:key" ) );
139 
140     }
141 
142     /**
143      * Just make sure that the LRU functions in he most simple case.
144      *
145      * @throws Exception
146      *                Description of the Exception
147      */
148     public void testLRURemoval()
149         throws Exception
150     {
151         int total = 10;
152         LRUMap<String, String> map = new LRUMap<String, String>( total );
153         map.setChunkSize( 1 );
154 
155         // put the max in
156         for ( int i = 0; i < total; i++ )
157         {
158             map.put( i + ":key", "data" + i );
159         }
160 
161         Iterator<?> it = map.entrySet().iterator();
162         while ( it.hasNext() )
163         {
164             assertNotNull( it.next() );
165         }
166 //        System.out.println( map.getStatistics() );
167 
168         // get the max out backwards
169         for ( int i = total - 1; i >= 0; i-- )
170         {
171             String res = map.get( i + ":key" );
172             assertNotNull( "[" + i + ":key] should not be null", res );
173         }
174 
175 //        System.out.println( map.getStatistics() );
176 
177         //since we got them backwards the total should be at the end.
178         // add one confirm that total is gone.
179         map.put( ( total ) + ":key", "data" + ( total ) );
180         assertNull( map.get( ( total - 1 ) + ":key" ) );
181 
182     }
183 
184     /**
185      * @throws Exception
186      */
187     public void testLRURemovalAgain()
188         throws Exception
189     {
190         int total = 10000;
191         LRUMap<String, String> map = new LRUMap<String, String>( total );
192         map.setChunkSize( 1 );
193 
194         // put the max in
195         for ( int i = 0; i < total * 2; i++ )
196         {
197             map.put( i + ":key", "data" + i );
198         }
199 
200         // get the total number, these should be null
201         for ( int i = total - 1; i >= 0; i-- )
202         {
203             assertNull( map.get( i + ":key" ) );
204 
205         }
206 
207         // get the total to total *2 items out, these should be found.
208         for ( int i = ( total * 2 ) - 1; i >= total; i-- )
209         {
210             String res = map.get( i + ":key" );
211             assertNotNull( "[" + i + ":key] should not be null", res );
212         }
213 
214 //        System.out.println( map.getStatistics() );
215 
216     }
217 
218     /**
219      * Just make sure that we can put and get concurrently
220      *
221      * @param map
222      * @param items
223      * @throws Exception
224      */
225     public void runConcurrentPutGetTests( LRUMap<String, String> map, int items )
226         throws Exception
227     {
228         for ( int i = 0; i < items; i++ )
229         {
230             map.put( i + ":key", "data" + i );
231         }
232 
233         for ( int i = items - 1; i >= 0; i-- )
234         {
235             String res = map.get( i + ":key" );
236             assertNotNull( "[" + i + ":key] should not be null", res );
237         }
238     }
239 
240     /**
241      * Put, get, and remove from a range. This should occur at a range that is
242      * not touched by other tests.
243      * <p>
244      * @param map
245      * @param start
246      * @param end
247      * @throws Exception
248      */
249     public void runConcurrentRangeTests( LRUMap<String, String> map, int start, int end )
250         throws Exception
251     {
252         for ( int i = start; i < end; i++ )
253         {
254             map.put( i + ":key", "data" + i );
255         }
256 
257         for ( int i = end - 1; i >= start; i-- )
258         {
259             String res = map.get( i + ":key" );
260             assertNotNull( "[" + i + ":key] should not be null", res );
261         }
262 
263         // test removal
264         map.remove( start + ":key" );
265         assertNull( map.get( start + ":key" ) );
266     }
267 }