1 package org.apache.directmemory.memory;
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.BenchmarkOptions;
23 import com.carrotsearch.junitbenchmarks.annotation.AxisRange;
24 import com.carrotsearch.junitbenchmarks.annotation.BenchmarkHistoryChart;
25 import com.carrotsearch.junitbenchmarks.annotation.BenchmarkMethodChart;
26 import com.carrotsearch.junitbenchmarks.annotation.LabelType;
27 import com.google.common.collect.MapMaker;
28 import org.apache.directmemory.measures.Ram;
29 import org.apache.directmemory.memory.MemoryManager;
30 import org.apache.directmemory.memory.Pointer;
31 import org.junit.AfterClass;
32 import org.junit.BeforeClass;
33 import org.junit.Ignore;
34 import org.junit.Test;
35 import org.slf4j.Logger;
36 import org.slf4j.LoggerFactory;
37
38 import java.util.Random;
39 import java.util.concurrent.ConcurrentMap;
40 import java.util.concurrent.atomic.AtomicInteger;
41
42 @AxisRange( min = 0, max = 1 )
43 @BenchmarkMethodChart()
44 @BenchmarkHistoryChart( labelWith = LabelType.CUSTOM_KEY, maxRuns = 5 )
45 @Ignore
46 public class Concurrent3Test
47 {
48
49 private final static int entries = 100000;
50
51 public static AtomicInteger count = new AtomicInteger();
52
53 private static AtomicInteger got = new AtomicInteger();
54
55 private static AtomicInteger missed = new AtomicInteger();
56
57 private static AtomicInteger good = new AtomicInteger();
58
59 private static AtomicInteger bad = new AtomicInteger();
60
61 private static AtomicInteger read = new AtomicInteger();
62
63 private static AtomicInteger disposals = new AtomicInteger();
64
65 public static ConcurrentMap<String, Pointer<Object>> map =
66 new MapMaker().concurrencyLevel( 4 ).initialCapacity( 100000 ).makeMap();
67
68
69 @BenchmarkOptions( benchmarkRounds = 100000, 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 = 500, 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 = 1000000, warmupRounds = 0, concurrency = 100 )
86 @Test
87 public void retrieveCatchThemAll()
88 {
89 String key = "test-" + ( rndGen.nextInt( entries ) + 1 );
90 get( key );
91 }
92
93 @BenchmarkOptions( benchmarkRounds = 1000000, warmupRounds = 0, concurrency = 100 )
94 @Test
95 public void retrieveCatchHalfOfThem()
96 {
97 String key = "test-" + ( rndGen.nextInt( entries * 2 ) + 1 );
98 get( key );
99 }
100
101 private void get( String key )
102 {
103 Pointer<Object> p = map.get( 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 map.put( key, MemoryManager.store( 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 map.put( key, MemoryManager.store( 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( Concurrent3Test.class );
227
228 private static void dump( MemoryManagerService<Object> mms )
229 {
230 logger.info( "off-heap - allocated: " + Ram.inMb( mms.capacity() ) );
231 logger.info( "off-heap - used: " + Ram.inMb( mms.used() ) );
232 logger.info( "heap - max: " + Ram.inMb( Runtime.getRuntime().maxMemory() ) );
233 logger.info( "heap - allocated: " + Ram.inMb( Runtime.getRuntime().totalMemory() ) );
234 logger.info( "heap - free : " + Ram.inMb( Runtime.getRuntime().freeMemory() ) );
235 logger.info( "************************************************" );
236 }
237
238 @BeforeClass
239 public static void init()
240 {
241 MemoryManager.init( 1, Ram.Mb( 512 ) );
242 }
243
244 @AfterClass
245 public static void dump()
246 {
247
248 dump( MemoryManager.getMemoryManager() );
249
250 logger.info( "************************************************" );
251 logger.info( "entries: " + entries );
252 logger.info( "inserted: " + map.size() );
253 logger.info( "reads: " + read );
254 logger.info( "count: " + count );
255 logger.info( "got: " + got );
256 logger.info( "missed: " + missed );
257 logger.info( "good: " + good );
258 logger.info( "bad: " + bad );
259 logger.info( "disposals: " + disposals );
260 logger.info( "************************************************" );
261 }
262
263 }
264
265
266