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