lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hoss...@apache.org
Subject svn commit: r938708 - in /lucene/dev/trunk/solr: ./ src/java/org/apache/solr/search/ src/test/org/apache/solr/search/
Date Tue, 27 Apr 2010 22:40:55 GMT
Author: hossman
Date: Tue Apr 27 22:40:55 2010
New Revision: 938708

URL: http://svn.apache.org/viewvc?rev=938708&view=rev
Log:
SOLR-571: autowarmCount on SolrCaches now supports relative percentages

Added:
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java   (with props)
    lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java   (with props)
Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/FastLRUCache.java
    lucene/dev/trunk/solr/src/java/org/apache/solr/search/LRUCache.java
    lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestFastLRUCache.java

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=938708&r1=938707&r2=938708&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Tue Apr 27 22:40:55 2010
@@ -139,6 +139,11 @@ New Features
 * SOLR-1740: ShingleFilterFactory supports the "minShingleSize" and "tokenSeparator"
   parameters for controlling the minimum shingle size produced by the filter, and
   the separator string that it uses, respectively.  (Steven Rowe via rmuir)
+  
+* SOLR-571: The autowarmCount for LRUCaches (LRUCache and FastLRUCache) now 
+  supports "percentages" which get evaluated  relative the current size of 
+  the cache when warming happens. 
+  (Tomas Fernandez Lobbe and hossman)
    
 Optimizations
 ----------------------

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/FastLRUCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/FastLRUCache.java?rev=938708&r1=938707&r2=938708&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/FastLRUCache.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/FastLRUCache.java Tue Apr 27 22:40:55
2010
@@ -43,7 +43,7 @@ import java.util.concurrent.CopyOnWriteA
  * @see org.apache.solr.search.SolrCache
  * @since solr 1.4
  */
-public class FastLRUCache<K,V> implements SolrCache<K,V> {
+public class FastLRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V>
{
 
   // contains the statistics objects for all open caches of the same type
   private List<ConcurrentLRUCache.Stats> statsList;
@@ -51,7 +51,7 @@ public class FastLRUCache<K,V> implement
   private long warmupTime = 0;
 
   private String name;
-  private int autowarmCount;
+  private AutoWarmCountRef autowarm;
   private State state;
   private CacheRegenerator regenerator;
   private String description = "Concurrent LRU Cache";
@@ -86,8 +86,7 @@ public class FastLRUCache<K,V> implement
 
     str = (String) args.get("initialSize");
     final int initialSize = str == null ? limit : Integer.parseInt(str);
-    str = (String) args.get("autowarmCount");
-    autowarmCount = str == null ? 0 : Integer.parseInt(str);
+    autowarm = new AutoWarmCountRef((String)args.get("autowarmCount"));
     str = (String) args.get("cleanupThread");
     boolean newThread = str == null ? false : Boolean.parseBoolean(str);
 
@@ -97,8 +96,8 @@ public class FastLRUCache<K,V> implement
 
     description = "Concurrent LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize
+
             ", minSize="+minLimit + ", acceptableSize="+acceptableLimit+", cleanupThread="+newThread;
-    if (autowarmCount > 0) {
-      description += ", autowarmCount=" + autowarmCount + ", regenerator=" + regenerator;
+    if (autowarm.isAutoWarmingOn()) {
+      description += ", autowarmCount=" + autowarm + ", regenerator=" + regenerator;
     }
     description += ')';
 
@@ -154,9 +153,8 @@ public class FastLRUCache<K,V> implement
     long warmingStartTime = System.currentTimeMillis();
     FastLRUCache other = (FastLRUCache) old;
     // warm entries
-    if (autowarmCount != 0) {
-      int sz = other.size();
-      if (autowarmCount != -1) sz = Math.min(sz, autowarmCount);
+    if (autowarm.isAutoWarmingOn()) {
+      int sz = autowarm.getWarmCount(other.size());
       Map items = other.cache.getLatestAccessedItems(sz);
       Map.Entry[] itemsArr = new Map.Entry[items.size()];
       int counter = 0;

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/LRUCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/LRUCache.java?rev=938708&r1=938707&r2=938708&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/LRUCache.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/LRUCache.java Tue Apr 27 22:40:55
2010
@@ -31,7 +31,7 @@ import java.net.URL;
 /**
  * @version $Id$
  */
-public class LRUCache<K,V> implements SolrCache<K,V> {
+public class LRUCache<K,V> extends SolrCacheBase implements SolrCache<K,V> {
 
   /* An instance of this class will be shared across multiple instances
    * of an LRUCache at the same time.  Make sure everything is thread safe.
@@ -56,7 +56,7 @@ public class LRUCache<K,V> implements So
 
   private Map<K,V> map;
   private String name;
-  private int autowarmCount;
+  private AutoWarmCountRef autowarm;
   private State state;
   private CacheRegenerator regenerator;
   private String description="LRU Cache";
@@ -69,13 +69,10 @@ public class LRUCache<K,V> implements So
     final int limit = str==null ? 1024 : Integer.parseInt(str);
     str = (String)args.get("initialSize");
     final int initialSize = Math.min(str==null ? 1024 : Integer.parseInt(str), limit);
-    str = (String)args.get("autowarmCount");
-    autowarmCount = str==null ? 0 : Integer.parseInt(str);
-
+    autowarm = new AutoWarmCountRef((String)args.get("autowarmCount"));
     description = "LRU Cache(maxSize=" + limit + ", initialSize=" + initialSize;
-    if (autowarmCount>0) {
-      description += ", autowarmCount=" + autowarmCount
-              + ", regenerator=" + regenerator;
+    if (autowarm.isAutoWarmingOn()) {
+      description += ", autowarmCount=" + autowarm + ", regenerator=" + regenerator;
     }
     description += ')';
 
@@ -162,13 +159,14 @@ public class LRUCache<K,V> implements So
     LRUCache<K,V> other = (LRUCache<K,V>)old;
 
     // warm entries
-    if (autowarmCount != 0) {
+    if (autowarm.isAutoWarmingOn()) {
       Object[] keys,vals = null;
 
       // Don't do the autowarming in the synchronized block, just pull out the keys and values.
       synchronized (other.map) {
-        int sz = other.map.size();
-        if (autowarmCount!=-1) sz = Math.min(sz,autowarmCount);
+        
+        int sz = autowarm.getWarmCount(other.map.size());
+        
         keys = new Object[sz];
         vals = new Object[sz];
 
@@ -254,7 +252,7 @@ public class LRUCache<K,V> implements So
     return Integer.toString(ones) + '.' + tenths;
     ***/
   }
-
+  
   public NamedList getStatistics() {
     NamedList lst = new SimpleOrderedMap();
     synchronized (map) {

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java?rev=938708&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java Tue Apr 27 22:40:55
2010
@@ -0,0 +1,81 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.solr.search;
+
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.util.NamedList;
+import org.apache.solr.common.util.SimpleOrderedMap;
+import org.apache.solr.core.SolrCore;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicLong;
+import java.io.IOException;
+import java.net.URL;
+
+/**
+ * Common base class of reusable functionality for SolrCaches
+ */
+public abstract class SolrCacheBase {
+
+  /**
+   * Decides how many things to autowarm based on the size of another cache
+   */
+  public static class AutoWarmCountRef {
+
+    private final int autoWarmCount;
+    private final int autoWarmPercentage;
+    private final boolean autoWarmByPercentage;
+    private final boolean doAutoWarming;
+    private final String strVal;
+    public AutoWarmCountRef(final String configValue) {
+      try {
+        String input = (null == configValue) ? "0" : configValue.trim();
+
+        // odd undocumented legacy behavior, -1 ment "all" (now "100%")
+        strVal = ("-1".equals(input)) ? "100%" : input;
+
+        if (strVal.indexOf("%") == (strVal.length() - 1)) {
+          autoWarmCount = 0;
+          autoWarmPercentage = Integer.parseInt(strVal.substring(0, strVal.length() - 1));
+          autoWarmByPercentage = true;
+          doAutoWarming = (0 < autoWarmPercentage);
+        } else {
+          autoWarmCount = Integer.parseInt(strVal);
+          autoWarmPercentage = 0;
+          autoWarmByPercentage = false;
+          doAutoWarming = (0 < autoWarmCount);
+        }
+
+      } catch (Exception e) {
+        throw new RuntimeException("Can't parse autoWarm value: " + configValue, e);
+      }
+    }
+    public String toString() {
+      return strVal;
+    }
+    public boolean isAutoWarmingOn() {
+      return doAutoWarming;
+    }
+    public int getWarmCount(final int previousCacheSize) {
+      return autoWarmByPercentage ? 
+        (previousCacheSize * autoWarmPercentage)/100 :
+        Math.min(previousCacheSize, autoWarmCount);
+    }
+  }
+}
+

Propchange: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SolrCacheBase.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestFastLRUCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestFastLRUCache.java?rev=938708&r1=938707&r2=938708&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestFastLRUCache.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestFastLRUCache.java Tue Apr 27
22:40:55 2010
@@ -21,6 +21,7 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.common.util.ConcurrentLRUCache;
 
 import java.io.IOException;
+import java.io.Serializable;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Random;
@@ -35,19 +36,164 @@ import java.util.concurrent.atomic.Atomi
  * @since solr 1.4
  */
 public class TestFastLRUCache extends TestCase {
+  
+  public void testPercentageAutowarm() throws IOException {
+    FastLRUCache<Object, Object> fastCache = new FastLRUCache<Object, Object>();
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("size", "100");
+    params.put("initialSize", "10");
+    params.put("autowarmCount", "100%");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = fastCache.init(params, null, cr);
+    fastCache.setState(SolrCache.State.LIVE);
+    for (int i = 0; i < 101; i++) {
+      fastCache.put(i + 1, "" + (i + 1));
+    }
+    assertEquals("25", fastCache.get(25));
+    assertEquals(null, fastCache.get(110));
+    NamedList<Serializable> nl = fastCache.getStatistics();
+    assertEquals(2L, nl.get("lookups"));
+    assertEquals(1L, nl.get("hits"));
+    assertEquals(101L, nl.get("inserts"));
+    assertEquals(null, fastCache.get(1));  // first item put in should be the first out
+    FastLRUCache<Object, Object> fastCacheNew = new FastLRUCache<Object, Object>();
+    fastCacheNew.init(params, o, cr);
+    fastCacheNew.warm(null, fastCache);
+    fastCacheNew.setState(SolrCache.State.LIVE);
+    fastCache.close();
+    fastCacheNew.put(103, "103");
+    assertEquals("90", fastCacheNew.get(90));
+    assertEquals("50", fastCacheNew.get(50));
+    nl = fastCacheNew.getStatistics();
+    assertEquals(2L, nl.get("lookups"));
+    assertEquals(2L, nl.get("hits"));
+    assertEquals(1L, nl.get("inserts"));
+    assertEquals(0L, nl.get("evictions"));
+    assertEquals(5L, nl.get("cumulative_lookups"));
+    assertEquals(3L, nl.get("cumulative_hits"));
+    assertEquals(102L, nl.get("cumulative_inserts"));
+    fastCacheNew.close();
+  }
+  
+  public void testPercentageAutowarmMultiple() throws IOException {
+    doTestPercentageAutowarm(100, 50, new int[]{51, 55, 60, 70, 80, 99, 100}, new int[]{1,
2, 3, 5, 10, 20, 30, 40, 50});
+    doTestPercentageAutowarm(100, 25, new int[]{76, 80, 99, 100}, new int[]{1, 2, 3, 5, 10,
20, 30, 40, 50, 51, 55, 60, 70});
+    doTestPercentageAutowarm(1000, 10, new int[]{901, 930, 950, 999, 1000}, new int[]{1,
5, 100, 200, 300, 400, 800, 899, 900});
+    doTestPercentageAutowarm(100, 200, new int[]{1, 10, 25, 51, 55, 60, 70, 80, 99, 100},
new int[]{200, 300});
+    doTestPercentageAutowarm(100, 0, new int[]{}, new int[]{1, 10, 25, 51, 55, 60, 70, 80,
99, 100, 200, 300});
+  }
+  
+  private void doTestPercentageAutowarm(int limit, int percentage, int[] hits, int[]misses)
throws IOException {
+    FastLRUCache<Object, Object> fastCache = new FastLRUCache<Object, Object>();
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("size", String.valueOf(limit));
+    params.put("initialSize", "10");
+    params.put("autowarmCount", percentage + "%");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = fastCache.init(params, null, cr);
+    fastCache.setState(SolrCache.State.LIVE);
+    for (int i = 1; i <= limit; i++) {
+      fastCache.put(i, "" + i);//adds numbers from 1 to 100
+    }
+
+    FastLRUCache<Object, Object> fastCacheNew = new FastLRUCache<Object, Object>();
+    fastCacheNew.init(params, o, cr);
+    fastCacheNew.warm(null, fastCache);
+    fastCacheNew.setState(SolrCache.State.LIVE);
+    fastCache.close();
+      
+    for(int hit:hits) {
+      assertEquals("The value " + hit + " should be on new cache", String.valueOf(hit), fastCacheNew.get(hit));
+    }
+      
+    for(int miss:misses) {
+      assertEquals("The value " + miss + " should NOT be on new cache", null, fastCacheNew.get(miss));
+    }
+    NamedList<Serializable> nl = fastCacheNew.getStatistics();
+    assertEquals(Long.valueOf(hits.length + misses.length), nl.get("lookups"));
+    assertEquals(Long.valueOf(hits.length), nl.get("hits"));
+    fastCacheNew.close();
+  }
+  
+  public void testNoAutowarm() throws IOException {
+    FastLRUCache<Object, Object> fastCache = new FastLRUCache<Object, Object>();
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("size", "100");
+    params.put("initialSize", "10");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = fastCache.init(params, null, cr);
+    fastCache.setState(SolrCache.State.LIVE);
+    for (int i = 0; i < 101; i++) {
+      fastCache.put(i + 1, "" + (i + 1));
+    }
+    assertEquals("25", fastCache.get(25));
+    assertEquals(null, fastCache.get(110));
+    NamedList<Serializable> nl = fastCache.getStatistics();
+    assertEquals(2L, nl.get("lookups"));
+    assertEquals(1L, nl.get("hits"));
+    assertEquals(101L, nl.get("inserts"));
+    assertEquals(null, fastCache.get(1));  // first item put in should be the first out
+    FastLRUCache<Object, Object> fastCacheNew = new FastLRUCache<Object, Object>();
+    fastCacheNew.init(params, o, cr);
+    fastCacheNew.warm(null, fastCache);
+    fastCacheNew.setState(SolrCache.State.LIVE);
+    fastCache.close();
+    fastCacheNew.put(103, "103");
+    assertEquals(null, fastCacheNew.get(90));
+    assertEquals(null, fastCacheNew.get(50));
+    fastCacheNew.close();
+  }
+  
+  public void testFullAutowarm() throws IOException {
+    FastLRUCache<Object, Object> cache = new FastLRUCache<Object, Object>();
+    Map<Object, Object> params = new HashMap<Object, Object>();
+    params.put("size", "100");
+    params.put("initialSize", "10");
+    params.put("autowarmCount", "-1");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = cache.init(params, null, cr);
+    cache.setState(SolrCache.State.LIVE);
+    for (int i = 0; i < 101; i++) {
+      cache.put(i + 1, "" + (i + 1));
+    }
+    assertEquals("25", cache.get(25));
+    assertEquals(null, cache.get(110));
+
+    assertEquals(null, cache.get(1));  // first item put in should be the first out
+
+
+    FastLRUCache<Object, Object> cacheNew = new FastLRUCache<Object, Object>();
+    cacheNew.init(params, o, cr);
+    cacheNew.warm(null, cache);
+    cacheNew.setState(SolrCache.State.LIVE);
+    cache.close();
+    cacheNew.put(103, "103");
+    assertEquals("90", cacheNew.get(90));
+    assertEquals("50", cacheNew.get(50));
+    assertEquals("103", cacheNew.get(103));
+    cacheNew.close();
+  }
+
+  private CacheRegenerator createCodeRegenerator() {
+    CacheRegenerator cr = new CacheRegenerator() {
+        public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache,
+                                      SolrCache oldCache, Object oldKey, Object oldVal) throws
IOException {
+          newCache.put(oldKey, oldVal);
+          return true;
+        }
+      };
+    return cr;
+  }
+  
+  
+  
   public void testSimple() throws IOException {
     FastLRUCache sc = new FastLRUCache();
     Map l = new HashMap();
     l.put("size", "100");
     l.put("initialSize", "10");
     l.put("autowarmCount", "25");
-    CacheRegenerator cr = new CacheRegenerator() {
-      public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache,
-                                    SolrCache oldCache, Object oldKey, Object oldVal) throws
IOException {
-        newCache.put(oldKey, oldVal);
-        return true;
-      }
-    };
+    CacheRegenerator cr = createCodeRegenerator();
     Object o = sc.init(l, null, cr);
     sc.setState(SolrCache.State.LIVE);
     for (int i = 0; i < 101; i++) {
@@ -128,13 +274,13 @@ public class TestFastLRUCache extends Te
   }
 
   /***
-  public void testPerf() {
-    doPerfTest(1000000, 100000, 200000); // big cache, warmup
-    doPerfTest(2000000, 100000, 200000); // big cache
-    doPerfTest(2000000, 100000, 120000);  // smaller key space increases distance between
oldest, newest and makes the first passes less effective.
-    doPerfTest(6000000, 1000, 2000);    // small cache, smaller hit rate
-    doPerfTest(6000000, 1000, 1200);    // small cache, bigger hit rate
-  }
+      public void testPerf() {
+      doPerfTest(1000000, 100000, 200000); // big cache, warmup
+      doPerfTest(2000000, 100000, 200000); // big cache
+      doPerfTest(2000000, 100000, 120000);  // smaller key space increases distance between
oldest, newest and makes the first passes less effective.
+      doPerfTest(6000000, 1000, 2000);    // small cache, smaller hit rate
+      doPerfTest(6000000, 1000, 1200);    // small cache, bigger hit rate
+      }
   ***/
 
   // returns number of puts
@@ -181,11 +327,11 @@ public class TestFastLRUCache extends Te
     for (int i=0; i<threads.length; i++) {
       final int seed=i;
       threads[i] = new Thread() {
-        public void run() {
-          int ret = useCache(sc, numGets/nThreads, maxKey, seed);
-          puts.addAndGet(ret);
-        }
-      };
+          public void run() {
+            int ret = useCache(sc, numGets/nThreads, maxKey, seed);
+            puts.addAndGet(ret);
+          }
+        };
     }
 
     for (Thread thread : threads) {
@@ -206,8 +352,8 @@ public class TestFastLRUCache extends Te
 
     long end = System.currentTimeMillis();
     System.out.println("time=" + (end-start) + " impl=" +sc.getClass().getSimpleName()
-            +" nThreads= " + nThreads + " size="+cacheSize+" maxKey="+maxKey+" gets="+numGets
-            +" hitRatio="+(1-(((double)puts.get())/numGets)));
+                       +" nThreads= " + nThreads + " size="+cacheSize+" maxKey="+maxKey+"
gets="+numGets
+                       +" hitRatio="+(1-(((double)puts.get())/numGets)));
   }
 
   void perfTestBoth(int nThreads, int numGets, int cacheSize, int maxKey) {
@@ -216,27 +362,27 @@ public class TestFastLRUCache extends Te
   }
 
   /***
-  public void testCachePerf() {
-    // warmup
-    perfTestBoth(2, 100000, 100000, 120000);
-    perfTestBoth(1, 2000000, 100000, 100000); // big cache, 100% hit ratio
-    perfTestBoth(2, 2000000, 100000, 100000); // big cache, 100% hit ratio
-    perfTestBoth(1, 2000000, 100000, 120000); // big cache, bigger hit ratio
-    perfTestBoth(2, 2000000, 100000, 120000); // big cache, bigger hit ratio
-    perfTestBoth(1, 2000000, 100000, 200000); // big cache, ~50% hit ratio
-    perfTestBoth(2, 2000000, 100000, 200000); // big cache, ~50% hit ratio
-    perfTestBoth(1, 2000000, 100000, 1000000); // big cache, ~10% hit ratio
-    perfTestBoth(2, 2000000, 100000, 1000000); // big cache, ~10% hit ratio
-
-    perfTestBoth(1, 2000000, 1000, 1000); // small cache, ~100% hit ratio
-    perfTestBoth(2, 2000000, 1000, 1000); // small cache, ~100% hit ratio
-    perfTestBoth(1, 2000000, 1000, 1200); // small cache, bigger hit ratio
-    perfTestBoth(2, 2000000, 1000, 1200); // small cache, bigger hit ratio
-    perfTestBoth(1, 2000000, 1000, 2000); // small cache, ~50% hit ratio
-    perfTestBoth(2, 2000000, 1000, 2000); // small cache, ~50% hit ratio
-    perfTestBoth(1, 2000000, 1000, 10000); // small cache, ~10% hit ratio
-    perfTestBoth(2, 2000000, 1000, 10000); // small cache, ~10% hit ratio
-  }
+      public void testCachePerf() {
+      // warmup
+      perfTestBoth(2, 100000, 100000, 120000);
+      perfTestBoth(1, 2000000, 100000, 100000); // big cache, 100% hit ratio
+      perfTestBoth(2, 2000000, 100000, 100000); // big cache, 100% hit ratio
+      perfTestBoth(1, 2000000, 100000, 120000); // big cache, bigger hit ratio
+      perfTestBoth(2, 2000000, 100000, 120000); // big cache, bigger hit ratio
+      perfTestBoth(1, 2000000, 100000, 200000); // big cache, ~50% hit ratio
+      perfTestBoth(2, 2000000, 100000, 200000); // big cache, ~50% hit ratio
+      perfTestBoth(1, 2000000, 100000, 1000000); // big cache, ~10% hit ratio
+      perfTestBoth(2, 2000000, 100000, 1000000); // big cache, ~10% hit ratio
+
+      perfTestBoth(1, 2000000, 1000, 1000); // small cache, ~100% hit ratio
+      perfTestBoth(2, 2000000, 1000, 1000); // small cache, ~100% hit ratio
+      perfTestBoth(1, 2000000, 1000, 1200); // small cache, bigger hit ratio
+      perfTestBoth(2, 2000000, 1000, 1200); // small cache, bigger hit ratio
+      perfTestBoth(1, 2000000, 1000, 2000); // small cache, ~50% hit ratio
+      perfTestBoth(2, 2000000, 1000, 2000); // small cache, ~50% hit ratio
+      perfTestBoth(1, 2000000, 1000, 10000); // small cache, ~10% hit ratio
+      perfTestBoth(2, 2000000, 1000, 10000); // small cache, ~10% hit ratio
+      }
   ***/
 
 

Added: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java?rev=938708&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java (added)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java Tue Apr 27 22:40:55
2010
@@ -0,0 +1,120 @@
+package org.apache.solr.search;
+
+import java.io.IOException;
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestCase;
+
+import org.apache.solr.common.util.NamedList;
+
+/**
+ * Test for <code>org.apache.solr.search.LRUCache</code>
+ */
+public class TestLRUCache extends TestCase {
+
+  public void testFullAutowarm() throws IOException {
+    LRUCache<Object, Object> lruCache = new LRUCache<Object, Object>();
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("size", "100");
+    params.put("initialSize", "10");
+    params.put("autowarmCount", "100%");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = lruCache.init(params, null, cr);
+    lruCache.setState(SolrCache.State.LIVE);
+    for (int i = 0; i < 101; i++) {
+      lruCache.put(i + 1, "" + (i + 1));
+    }
+    assertEquals("25", lruCache.get(25));
+    assertEquals(null, lruCache.get(110));
+    assertEquals(null, lruCache.get(1));  // first item put in should be the first out
+    LRUCache<Object, Object> lruCacheNew = new LRUCache<Object, Object>();
+    lruCacheNew.init(params, o, cr);
+    lruCacheNew.warm(null, lruCache);
+    lruCacheNew.setState(SolrCache.State.LIVE);
+    lruCache.close();
+    lruCacheNew.put(103, "103");
+    assertEquals("90", lruCacheNew.get(90));
+    assertEquals("50", lruCacheNew.get(50));
+    lruCacheNew.close();
+  }
+  
+  public void testPercentageAutowarm() throws IOException {
+      doTestPercentageAutowarm(100, 50, new int[]{51, 55, 60, 70, 80, 99, 100}, new int[]{1,
2, 3, 5, 10, 20, 30, 40, 50});
+      doTestPercentageAutowarm(100, 25, new int[]{76, 80, 99, 100}, new int[]{1, 2, 3, 5,
10, 20, 30, 40, 50, 51, 55, 60, 70});
+      doTestPercentageAutowarm(1000, 10, new int[]{901, 930, 950, 999, 1000}, new int[]{1,
5, 100, 200, 300, 400, 800, 899, 900});
+      doTestPercentageAutowarm(10, 10, new int[]{10}, new int[]{1, 5, 9, 100, 200, 300, 400,
800, 899, 900});
+  }
+  
+  private void doTestPercentageAutowarm(int limit, int percentage, int[] hits, int[]misses)
throws IOException {
+    LRUCache<Object, Object> lruCache = new LRUCache<Object, Object>();
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("size", String.valueOf(limit));
+    params.put("initialSize", "10");
+    params.put("autowarmCount", percentage + "%");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = lruCache.init(params, null, cr);
+    lruCache.setState(SolrCache.State.LIVE);
+    for (int i = 1; i <= limit; i++) {
+      lruCache.put(i, "" + i);//adds numbers from 1 to 100
+    }
+
+    LRUCache<Object, Object> lruCacheNew = new LRUCache<Object, Object>();
+    lruCacheNew.init(params, o, cr);
+    lruCacheNew.warm(null, lruCache);
+    lruCacheNew.setState(SolrCache.State.LIVE);
+    lruCache.close();
+      
+    for(int hit:hits) {
+      assertEquals("The value " + hit + " should be on new cache", String.valueOf(hit), lruCacheNew.get(hit));
+    }
+      
+    for(int miss:misses) {
+      assertEquals("The value " + miss + " should NOT be on new cache", null, lruCacheNew.get(miss));
+    }
+    lruCacheNew.close();
+  }
+  
+  @SuppressWarnings("unchecked")
+  public void testNoAutowarm() throws IOException {
+    LRUCache<Object, Object> lruCache = new LRUCache<Object, Object>();
+    Map<String, String> params = new HashMap<String, String>();
+    params.put("size", "100");
+    params.put("initialSize", "10");
+    CacheRegenerator cr = createCodeRegenerator();
+    Object o = lruCache.init(params, null, cr);
+    lruCache.setState(SolrCache.State.LIVE);
+    for (int i = 0; i < 101; i++) {
+      lruCache.put(i + 1, "" + (i + 1));
+    }
+    assertEquals("25", lruCache.get(25));
+    assertEquals(null, lruCache.get(110));
+    NamedList<Serializable> nl = lruCache.getStatistics();
+    assertEquals(2L, nl.get("lookups"));
+    assertEquals(1L, nl.get("hits"));
+    assertEquals(101L, nl.get("inserts"));
+    assertEquals(null, lruCache.get(1));  // first item put in should be the first out
+    LRUCache<Object, Object> lruCacheNew = new LRUCache<Object, Object>();
+    lruCacheNew.init(params, o, cr);
+    lruCacheNew.warm(null, lruCache);
+    lruCacheNew.setState(SolrCache.State.LIVE);
+    lruCache.close();
+    lruCacheNew.put(103, "103");
+    assertEquals(null, lruCacheNew.get(90));
+    assertEquals(null, lruCacheNew.get(50));
+    lruCacheNew.close();
+  }
+  
+  private CacheRegenerator createCodeRegenerator() {
+    CacheRegenerator cr = new CacheRegenerator() {
+      @SuppressWarnings("unchecked")
+      public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache,
+                                    SolrCache oldCache, Object oldKey, Object oldVal) throws
IOException {
+        newCache.put(oldKey, oldVal);
+        return true;
+      }
+    };
+    return cr;
+  }
+}

Propchange: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: lucene/dev/trunk/solr/src/test/org/apache/solr/search/TestLRUCache.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL



Mime
View raw message