1 package org.apache.directmemory.cache;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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