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 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