View Javadoc

1   package org.apache.directmemory.guava;
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.google.common.cache.Cache;
23  import com.google.common.cache.CacheBuilder;
24  import com.google.common.collect.Iterables;
25  import com.google.common.collect.Lists;
26  import org.apache.directmemory.DirectMemory;
27  import org.apache.directmemory.cache.CacheService;
28  import org.junit.Test;
29  
30  import java.util.Map;
31  import java.util.concurrent.Callable;
32  import java.util.concurrent.ExecutionException;
33  
34  import static org.junit.Assert.assertEquals;
35  import static org.junit.Assert.assertNull;
36  
37  public class GuavaCacheTest
38  {
39  
40      private int maxSize = 100;
41  
42      private int offHeapSize = 20;
43  
44      private Cache<Integer, Integer> primaryCache;
45  
46      private CacheService<Integer, Integer> cacheService;
47  
48      private OffHeapCache<Integer, Integer> cache;
49  
50      @Test
51      public void testEviction()
52      {
53          createScenario();
54  
55          //No of entries in off heap cache should be equal to the extra entries
56          //over and above the maxSize specified for Cache as those would be evicted
57          assertEquals( offHeapSize, cacheService.entries() );
58  
59          for ( int i = 0; i < maxSize + offHeapSize; i++ )
60          {
61              Integer ignored = cache.getIfPresent( i );
62          }
63  
64          assertEquals( offHeapSize, cache.offHeapStats().loadCount() );
65      }
66  
67      @Test
68      public void testWithLoader()
69          throws ExecutionException
70      {
71          createScenario();
72  
73          Callable<Integer> testCallable = new Callable<Integer>()
74          {
75              @Override
76              public Integer call()
77                  throws Exception
78              {
79                  return -1;
80              }
81          };
82  
83          Integer result = cache.get( 1000, testCallable );
84          assertEquals( new Integer( -1 ), result );
85      }
86  
87      @Test
88      public void testInvalidate()
89      {
90          createScenario();
91  
92          //Find a key which is actually part of L2
93          Integer key = Iterables.get( cacheService.getMap().keySet(), 0 );
94  
95          cache.invalidate( key );
96  
97          assertNull( cacheService.retrieve( key ) );
98      }
99  
100     @Test
101     public void testInvalidateAllWithKeys()
102     {
103         createScenario();
104         Integer keyInL1 = Iterables.get( cache.asMap().keySet(), 0 );
105         Integer keyInL2 = Iterables.get( cacheService.getMap().keySet(), 0 );
106 
107         Iterable<Integer> keys = Lists.newArrayList( keyInL1, keyInL2 );
108         cache.invalidateAll( keys );
109 
110         assertNull( cacheService.retrieve( keyInL2 ) );
111         assertNull( cache.getIfPresent( keyInL1 ) );
112     }
113 
114     @Test
115     public void testInvalidateAll()
116     {
117         createScenario();
118         cache.invalidateAll();
119         assertEquals( 0, cacheService.entries() );
120     }
121 
122     @Test
123     public void getAllPresent()
124     {
125         createScenario();
126         Integer keyInL1 = Iterables.get( cache.asMap().keySet(), 0 );
127         Integer keyInL2 = Iterables.get( cacheService.getMap().keySet(), 0 );
128 
129         Iterable<Integer> keys = Lists.newArrayList( keyInL1, keyInL2, 1000 );
130         Map<Integer, Integer> result = cache.getAllPresent( keys );
131 
132         assertEquals( 2, result.size() );
133         assertEquals( result.get( keyInL1 ), keyInL1 );
134         assertEquals( result.get( keyInL2 ), keyInL2 );
135 
136         Iterable<Integer> keys2 = Lists.newArrayList( keyInL1 );
137         Map<Integer, Integer> result2 = cache.getAllPresent( keys2 );
138 
139         assertEquals( 1, result2.size() );
140         assertEquals( result2.get( keyInL1 ), keyInL1 );
141     }
142 
143     private void createScenario()
144     {
145         //1. First create a bridge listener
146         ForwardingListener<Integer, Integer> listener = ForwardingListener.newInstance();
147 
148         //2. Second create the Guava cache with the bridge listener
149         primaryCache = CacheBuilder.newBuilder().maximumSize( maxSize ).removalListener( listener ).build();
150 
151         //3. Create the CacheService
152         cacheService = new DirectMemory<Integer, Integer>().setNumberOfBuffers( 10 ).setSize( 1000 ).setInitialCapacity(
153             10000 ).setConcurrencyLevel( 4 ).newCacheService();
154 
155         //4. Create the L2 cache with bridge listener and Guava cache
156         cache = new OffHeapCache<Integer, Integer>( cacheService, primaryCache, listener );
157 
158         //Add number of entries so as to cause overflow and thus trigger eviction
159         for ( int i = 0; i < maxSize + offHeapSize; i++ )
160         {
161             cache.put( i, i );
162         }
163     }
164 
165 }