Guest User

Caffine hash clash

a guest
Apr 14th, 2016
122
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 5.65 KB | None | 0 0
  1. package org.apache.cassandra.cache;
  2.  
  3. import java.util.Iterator;
  4. import java.util.concurrent.ExecutionException;
  5.  
  6. import com.google.common.cache.Cache;
  7. import com.google.common.cache.CacheBuilder;
  8. import com.google.common.collect.ImmutableList;
  9. import com.google.common.util.concurrent.MoreExecutors;
  10.  
  11. import org.junit.Test;
  12.  
  13. import com.github.benmanes.caffeine.cache.Caffeine;
  14.  
  15. public class CacheHashClashTest
  16. {
  17.     private static final long ITERS = 200_000;
  18.     static final Long LONG_1 = Long.valueOf(1);
  19.    
  20.     interface ICache
  21.     {
  22.         public int size();
  23.  
  24.         public void put(Long key, Long value);
  25.  
  26.         public Long get(Long key);
  27.  
  28.         public void clear();
  29.  
  30.         public Iterator<Long> keyIterator();
  31.        
  32.         public long reqCount();
  33.  
  34.         public double hitRate();
  35.     }
  36.  
  37.     class GuavaCache implements ICache
  38.     {
  39.         final Cache<Long, Long> cache;
  40.  
  41.         public GuavaCache(long size)
  42.         {
  43.             cache = CacheBuilder.newBuilder()
  44.                     .maximumSize(size)
  45.                     .recordStats()
  46.                     .build();
  47.         }
  48.  
  49.         @Override
  50.         public int size()
  51.         {
  52.             return (int) cache.size();
  53.         }
  54.  
  55.         @Override
  56.         public void put(Long key, Long value)
  57.         {
  58.             cache.put(key, value);
  59.         }
  60.  
  61.         @Override
  62.         public Long get(Long key)
  63.         {
  64.             return cache.getIfPresent(key);
  65.         }
  66.  
  67.         @Override
  68.         public void clear()
  69.         {
  70.             cache.invalidateAll();
  71.         }
  72.  
  73.         @Override
  74.         public Iterator<Long> keyIterator()
  75.         {
  76.             return cache.asMap().keySet().iterator();
  77.         }
  78.        
  79.         public long reqCount()
  80.         {
  81.             return cache.stats().requestCount();
  82.         }
  83.        
  84.         public double hitRate()
  85.         {
  86.             return cache.stats().hitRate();
  87.         }
  88.     }
  89.  
  90.    
  91.     class CaffeineCache implements ICache
  92.     {
  93.         final com.github.benmanes.caffeine.cache.Cache<Long, Long> cache;
  94.  
  95.         public CaffeineCache(long size)
  96.         {
  97.             cache = Caffeine.newBuilder()
  98.                     .maximumSize(size)
  99.                     .executor(MoreExecutors.directExecutor())
  100.                     .recordStats()
  101.                     .build();
  102.         }
  103.  
  104.         @Override
  105.         public int size()
  106.         {
  107.             return (int) cache.asMap().size();
  108.         }
  109.  
  110.         @Override
  111.         public void put(Long key, Long value)
  112.         {
  113.             cache.put(key, value);
  114.         }
  115.  
  116.         @Override
  117.         public Long get(Long key)
  118.         {
  119.             return cache.getIfPresent(key);
  120.         }
  121.  
  122.         @Override
  123.         public void clear()
  124.         {
  125.             cache.invalidateAll();
  126.         }
  127.  
  128.         @Override
  129.         public Iterator<Long> keyIterator()
  130.         {
  131.             return cache.policy().eviction().get().hottest(10000000).keySet().iterator();
  132.         }
  133.        
  134.         public long reqCount()
  135.         {
  136.             return cache.stats().requestCount();
  137.         }
  138.        
  139.         public double hitRate()
  140.         {
  141.             return cache.stats().hitRate();
  142.         }
  143.     }
  144.  
  145.     ICache cache;
  146.  
  147.  
  148.     @Test
  149.     public void testGuava() throws InterruptedException, ExecutionException
  150.     {
  151.         testCache(new GuavaCache(150));
  152.     }
  153.  
  154.     @Test
  155.     public void testCaffeine() throws InterruptedException, ExecutionException
  156.     {
  157.         testCache(new CaffeineCache(150));
  158.     }
  159.  
  160.     public void testCache(ICache cacheToTest) throws InterruptedException, ExecutionException
  161.     {
  162.         cache = cacheToTest;
  163.  
  164.         long startTime = System.currentTimeMillis();
  165.         int STEP = 5;
  166.  
  167.         long i = 200000;
  168.  
  169.         for (long j = 0; j < 300; ++j)
  170.         {
  171.             get(1L);
  172.             get(j);
  173.         }
  174.         System.out.format("%s size %,d requests %,d hit ratio %f\n",
  175.                 cache.toString(),
  176.                 cache.size(),
  177.                 cache.reqCount(),
  178.                 cache.hitRate());
  179.         System.out.println(ImmutableList.copyOf(cache.keyIterator()));
  180.  
  181.         // add a hashcode clash for 1
  182.         {
  183.             Long CLASH = (i << 32) ^ i ^ 1;
  184.             assert CLASH.hashCode() == LONG_1.hashCode();
  185.             get(CLASH);
  186.             System.out.println(ImmutableList.copyOf(cache.keyIterator()));
  187.         }
  188.  
  189.         // repeat some entries to let CLASH flow to the probation head
  190.         for (long j = 0; j < 300; ++j)
  191.         {
  192.             get(1L);
  193.             get(j);
  194.         }
  195.         System.out.println(ImmutableList.copyOf(cache.keyIterator()));
  196.  
  197.         // Now run a repeating sequence which has a longer length than eden space size.
  198.         for (i = 0; i < ITERS; i += STEP)
  199.         {
  200.             get(1L);
  201.             for (long j = 0; j < STEP; ++j)
  202.                 get(-j);
  203.         }
  204.         System.out.println(ImmutableList.copyOf(cache.keyIterator()));
  205.  
  206.         long endTime = System.currentTimeMillis();
  207.         System.out.println();
  208.  
  209.         System.out.format("%s size %,d requests %,d hit ratio %f\n",
  210.                 cache.toString(),
  211.                 cache.size(),
  212.                 cache.reqCount(),
  213.                 cache.hitRate());
  214.         System.out.format("%,d lookups completed in %,d ms\n",
  215.                 ITERS, endTime - startTime);
  216.  
  217.         cache.clear();
  218.     }
  219.  
  220.     public Long get(Long key)
  221.     {
  222.         Long d = cache.get(key);
  223.         if (d == null)
  224.         {
  225.             d = load(key);
  226.             cache.put(key, d);
  227.         }
  228.         return d;
  229.     }
  230.  
  231.     public Long load(Long key)
  232.     {
  233.         return key;
  234.     }
  235. }
Advertisement
Add Comment
Please, Sign In to add comment