View Javadoc

1   package org.apache.directmemory.cache;
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 java.util.Random;
23  import java.util.concurrent.atomic.AtomicInteger;
24  
25  import org.apache.directmemory.measures.Every;
26  import org.apache.directmemory.measures.Monitor;
27  import org.apache.directmemory.measures.Ram;
28  import org.apache.directmemory.memory.MemoryManager;
29  import org.apache.directmemory.memory.Pointer;
30  import org.junit.AfterClass;
31  import org.junit.BeforeClass;
32  import org.junit.Ignore;
33  import org.junit.Test;
34  import org.slf4j.Logger;
35  import org.slf4j.LoggerFactory;
36  
37  import com.carrotsearch.junitbenchmarks.AbstractBenchmark;
38  import com.carrotsearch.junitbenchmarks.BenchmarkOptions;
39  import com.carrotsearch.junitbenchmarks.annotation.AxisRange;
40  import com.carrotsearch.junitbenchmarks.annotation.BenchmarkHistoryChart;
41  import com.carrotsearch.junitbenchmarks.annotation.BenchmarkMethodChart;
42  import com.carrotsearch.junitbenchmarks.annotation.LabelType;
43  
44  @AxisRange( min = 0, max = 1 )
45  @BenchmarkMethodChart()
46  @BenchmarkHistoryChart( labelWith = LabelType.CUSTOM_KEY, maxRuns = 5 )
47  
48  @Ignore
49  public class CacheLightConcurrentTest
50      extends AbstractBenchmark
51  {
52  
53      private final static int entries = 10000;
54  
55      public static AtomicInteger count = new AtomicInteger();
56  
57      private static AtomicInteger got = new AtomicInteger();
58  
59      private static AtomicInteger missed = new AtomicInteger();
60  
61      private static AtomicInteger good = new AtomicInteger();
62  
63      private static AtomicInteger bad = new AtomicInteger();
64  
65      private static AtomicInteger read = new AtomicInteger();
66  
67      private static AtomicInteger disposals = new AtomicInteger();
68  
69      @BenchmarkOptions( benchmarkRounds = 10000, warmupRounds = 0, concurrency = 100 )
70      @Test
71      public void store()
72      {
73          final String key = "test-" + count.incrementAndGet();
74          put( key );
75      }
76  
77      @BenchmarkOptions( benchmarkRounds = 50, warmupRounds = 0, concurrency = 10 )
78      @Test
79      public void storeSomeWithExpiry()
80      {
81          final String key = "test-" + count.incrementAndGet();
82          putWithExpiry( key );
83      }
84  
85      @BenchmarkOptions( benchmarkRounds = 100000, warmupRounds = 0, concurrency = 100 )
86      @Test
87      public void retrieveCatchThemAll()
88      {
89          String key = "test-" + ( rndGen.nextInt( entries ) + 1 );
90          getAndRetrieve( key );
91      }
92  
93      @BenchmarkOptions( benchmarkRounds = 100000, warmupRounds = 0, concurrency = 100 )
94      @Test
95      public void retrieveCatchHalfOfThem()
96      {
97          String key = "test-" + ( rndGen.nextInt( entries * 2 ) + 1 );
98          getAndRetrieve( key );
99      }
100 
101     @BenchmarkOptions( benchmarkRounds = 1, warmupRounds = 0, concurrency = 1 )
102     @Test
103     public void LFUEviction()
104         throws Exception
105     {
106         Cache.collectAll();
107     }
108 
109     private void getAndRetrieve( String key )
110     {
111         Pointer<Object> p = Cache.getPointer( key );
112         @SuppressWarnings( "unused" ) byte[] check = Cache.retrieveByteArray( key );
113         read.incrementAndGet();
114         if ( p != null )
115         {
116             got.incrementAndGet();
117             byte[] payload = MemoryManager.retrieve( p );
118             if ( ( new String( payload ) ).startsWith( key ) )
119             {
120                 good.incrementAndGet();
121             }
122             else
123             {
124                 bad.incrementAndGet();
125             }
126         }
127         else
128         {
129             missed.incrementAndGet();
130         }
131     }
132 
133     private void put( String key )
134     {
135         final StringBuilder bldr = new StringBuilder();
136         for ( int i = 0; i < 100; i++ )
137         {
138             bldr.append( key );
139         }
140         Cache.putByteArray( key, bldr.toString().getBytes() );
141     }
142 
143     private void putWithExpiry( String key )
144     {
145         final StringBuilder bldr = new StringBuilder();
146         for ( int i = 0; i < 100; i++ )
147         {
148             bldr.append( key );
149         }
150         Cache.putByteArray( key, bldr.toString().getBytes(), rndGen.nextInt( 2000 ) );
151     }
152 
153 
154     @BenchmarkOptions( benchmarkRounds = 5000, warmupRounds = 0, concurrency = 10 )
155     @Test
156     public void write1Read8AndSomeDisposal()
157     {
158         String key = "test-" + ( rndGen.nextInt( entries * 2 ) + 1 );
159 
160         int what = rndGen.nextInt( 10 );
161 
162         switch ( what )
163         {
164             case 0:
165                 put( key );
166                 break;
167             case 1:
168             case 2:
169             case 3:
170             case 4:
171             case 5:
172             case 6:
173             case 7:
174             case 8:
175                 getAndRetrieve( key );
176                 break;
177             default:
178                 final int rndVal = rndGen.nextInt( 100 );
179                 if ( rndVal > 98 )
180                 {
181                     disposals.incrementAndGet();
182                     final long start = System.currentTimeMillis();
183                     long howMany = MemoryManager.collectExpired();
184                     final long end = System.currentTimeMillis();
185                     logger.info( "" + howMany + " disposed in " + ( end - start ) + " milliseconds" );
186                 }
187         }
188 
189     }
190 
191     @BenchmarkOptions( benchmarkRounds = 100000, warmupRounds = 0, concurrency = 10 )
192     @Test
193     public void write3Read7()
194     {
195         String key = "test-" + ( rndGen.nextInt( entries * 2 ) + 1 );
196 
197         int what = rndGen.nextInt( 10 );
198 
199         switch ( what )
200         {
201             case 0:
202             case 1:
203             case 2:
204                 put( key );
205                 break;
206             default:
207                 getAndRetrieve( key );
208                 break;
209         }
210     }
211 
212     @BenchmarkOptions( benchmarkRounds = 100000, warmupRounds = 0, concurrency = 10 )
213     @Test
214     public void write1Read9()
215     {
216         String key = "test-" + ( rndGen.nextInt( entries * 2 ) + 1 );
217 
218         int what = rndGen.nextInt( 10 );
219 
220         switch ( what )
221         {
222             case 0:
223                 put( key );
224                 break;
225             default:
226                 getAndRetrieve( key );
227                 break;
228 
229         }
230 
231     }
232 
233     Random rndGen = new Random();
234 
235     private static Logger logger = LoggerFactory.getLogger( CacheLightConcurrentTest.class );
236 
237     @BeforeClass
238     public static void init()
239     {
240         Cache.init( 1, Ram.Mb( 128 ) );
241         Cache.scheduleDisposalEvery( Every.seconds( 1 ) );
242         Cache.dump();
243     }
244 
245     @AfterClass
246     public static void dump()
247     {
248 
249         Cache.dump();
250         Monitor.dump( "cache" );
251 
252         logger.info( "************************************************" );
253         logger.info( "entries: " + entries );
254         logger.info( "inserted: " + Cache.entries() );
255         logger.info( "reads: " + read );
256         logger.info( "count: " + count );
257         logger.info( "got: " + got );
258         logger.info( "missed: " + missed );
259         logger.info( "good: " + good );
260         logger.info( "bad: " + bad );
261         logger.info( "disposals: " + disposals );
262         logger.info( "************************************************" );
263     }
264 
265 }
266 
267 
268