View Javadoc

1   package org.apache.directmemory.memory;
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.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