~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to solr/core/src/test/org/apache/solr/search/TestFastLRUCache.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/**
2
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
3
 
 * contributor license agreements.  See the NOTICE file distributed with
4
 
 * this work for additional information regarding copyright ownership.
5
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
6
 
 * (the "License"); you may not use this file except in compliance with
7
 
 * the License.  You may obtain a copy of the License at
8
 
 *
9
 
 *     http://www.apache.org/licenses/LICENSE-2.0
10
 
 *
11
 
 * Unless required by applicable law or agreed to in writing, software
12
 
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 
 * See the License for the specific language governing permissions and
15
 
 * limitations under the License.
16
 
 */
17
 
package org.apache.solr.search;
18
 
 
19
 
import org.apache.lucene.util.LuceneTestCase;
20
 
import org.apache.solr.common.util.NamedList;
21
 
import org.apache.solr.util.ConcurrentLRUCache;
22
 
 
23
 
import java.io.IOException;
24
 
import java.util.HashMap;
25
 
import java.util.Map;
26
 
import java.util.Random;
27
 
import java.util.concurrent.atomic.AtomicInteger;
28
 
 
29
 
 
30
 
/**
31
 
 * Test for FastLRUCache
32
 
 *
33
 
 * @version $Id: TestFastLRUCache.java 1170772 2011-09-14 19:09:56Z sarowe $
34
 
 * @see org.apache.solr.search.FastLRUCache
35
 
 * @since solr 1.4
36
 
 */
37
 
public class TestFastLRUCache extends LuceneTestCase {
38
 
  public void testSimple() throws IOException {
39
 
    FastLRUCache sc = new FastLRUCache();
40
 
    Map l = new HashMap();
41
 
    l.put("size", "100");
42
 
    l.put("initialSize", "10");
43
 
    l.put("autowarmCount", "25");
44
 
    CacheRegenerator cr = new CacheRegenerator() {
45
 
      public boolean regenerateItem(SolrIndexSearcher newSearcher, SolrCache newCache,
46
 
                                    SolrCache oldCache, Object oldKey, Object oldVal) throws IOException {
47
 
        newCache.put(oldKey, oldVal);
48
 
        return true;
49
 
      }
50
 
    };
51
 
    Object o = sc.init(l, null, cr);
52
 
    sc.setState(SolrCache.State.LIVE);
53
 
    for (int i = 0; i < 101; i++) {
54
 
      sc.put(i + 1, "" + (i + 1));
55
 
    }
56
 
    assertEquals("25", sc.get(25));
57
 
    assertEquals(null, sc.get(110));
58
 
    NamedList nl = sc.getStatistics();
59
 
    assertEquals(2L, nl.get("lookups"));
60
 
    assertEquals(1L, nl.get("hits"));
61
 
    assertEquals(101L, nl.get("inserts"));
62
 
 
63
 
    assertEquals(null, sc.get(1));  // first item put in should be the first out
64
 
 
65
 
 
66
 
    FastLRUCache scNew = new FastLRUCache();
67
 
    scNew.init(l, o, cr);
68
 
    scNew.warm(null, sc);
69
 
    scNew.setState(SolrCache.State.LIVE);
70
 
    sc.close();
71
 
    scNew.put(103, "103");
72
 
    assertEquals("90", scNew.get(90));
73
 
    assertEquals(null, scNew.get(50));
74
 
    nl = scNew.getStatistics();
75
 
    assertEquals(2L, nl.get("lookups"));
76
 
    assertEquals(1L, nl.get("hits"));
77
 
    assertEquals(1L, nl.get("inserts"));
78
 
    assertEquals(0L, nl.get("evictions"));
79
 
 
80
 
    assertEquals(5L, nl.get("cumulative_lookups"));
81
 
    assertEquals(2L, nl.get("cumulative_hits"));
82
 
    assertEquals(102L, nl.get("cumulative_inserts"));
83
 
    scNew.close();
84
 
  }
85
 
 
86
 
  public void testOldestItems() {
87
 
    ConcurrentLRUCache<Integer, String> cache = new ConcurrentLRUCache<Integer, String>(100, 90);
88
 
    for (int i = 0; i < 50; i++) {
89
 
      cache.put(i + 1, "" + (i + 1));
90
 
    }
91
 
    cache.get(1);
92
 
    cache.get(3);
93
 
    Map<Integer, String> m = cache.getOldestAccessedItems(5);
94
 
    //7 6 5 4 2
95
 
    assertNotNull(m.get(7));
96
 
    assertNotNull(m.get(6));
97
 
    assertNotNull(m.get(5));
98
 
    assertNotNull(m.get(4));
99
 
    assertNotNull(m.get(2));
100
 
 
101
 
    m = cache.getOldestAccessedItems(0);
102
 
    assertTrue(m.isEmpty());
103
 
 
104
 
    //test this too
105
 
    m = cache.getLatestAccessedItems(0);
106
 
    assertTrue(m.isEmpty());
107
 
 
108
 
    cache.destroy();
109
 
  }
110
 
 
111
 
  void doPerfTest(int iter, int cacheSize, int maxKey) {
112
 
    long start = System.currentTimeMillis();
113
 
 
114
 
    int lowerWaterMark = cacheSize;
115
 
    int upperWaterMark = (int)(lowerWaterMark * 1.1);
116
 
 
117
 
    Random r = random;
118
 
    ConcurrentLRUCache cache = new ConcurrentLRUCache(upperWaterMark, lowerWaterMark, (upperWaterMark+lowerWaterMark)/2, upperWaterMark, false, false, null);
119
 
    boolean getSize=false;
120
 
    int minSize=0,maxSize=0;
121
 
    for (int i=0; i<iter; i++) {
122
 
      cache.put(r.nextInt(maxKey),"TheValue");
123
 
      int sz = cache.size();
124
 
      if (!getSize && sz >= cacheSize) {
125
 
        getSize = true;
126
 
        minSize = sz;
127
 
      } else {
128
 
        if (sz < minSize) minSize=sz;
129
 
        else if (sz > maxSize) maxSize=sz;
130
 
      }
131
 
    }
132
 
    cache.destroy();
133
 
 
134
 
    long end = System.currentTimeMillis();
135
 
    System.out.println("time=" + (end-start) + ", minSize="+minSize+",maxSize="+maxSize);
136
 
  }
137
 
 
138
 
  /***
139
 
  public void testPerf() {
140
 
    doPerfTest(1000000, 100000, 200000); // big cache, warmup
141
 
    doPerfTest(2000000, 100000, 200000); // big cache
142
 
    doPerfTest(2000000, 100000, 120000);  // smaller key space increases distance between oldest, newest and makes the first passes less effective.
143
 
    doPerfTest(6000000, 1000, 2000);    // small cache, smaller hit rate
144
 
    doPerfTest(6000000, 1000, 1200);    // small cache, bigger hit rate
145
 
  }
146
 
  ***/
147
 
 
148
 
  // returns number of puts
149
 
  int useCache(SolrCache sc, int numGets, int maxKey, int seed) {
150
 
    int ret = 0;
151
 
    Random r = new Random(seed);
152
 
 
153
 
    // use like a cache... gets and a put if not found
154
 
    for (int i=0; i<numGets; i++) {
155
 
      Integer k = r.nextInt(maxKey);
156
 
      Integer v = (Integer)sc.get(k);
157
 
      if (v == null) {
158
 
        sc.put(k, k);
159
 
        ret++;
160
 
      }
161
 
    }
162
 
 
163
 
    return ret;
164
 
  }
165
 
 
166
 
  void fillCache(SolrCache sc, int cacheSize, int maxKey) {
167
 
    for (int i=0; i<cacheSize; i++) {
168
 
      Integer kv = random.nextInt(maxKey);
169
 
      sc.put(kv,kv);
170
 
    }
171
 
  }
172
 
 
173
 
 
174
 
  void cachePerfTest(final SolrCache sc, final int nThreads, final int numGets, int cacheSize, final int maxKey) {
175
 
    Map l = new HashMap();
176
 
    l.put("size", ""+cacheSize);
177
 
    l.put("initialSize", ""+cacheSize);
178
 
 
179
 
    Object o = sc.init(l, null, null);
180
 
    sc.setState(SolrCache.State.LIVE);
181
 
 
182
 
    fillCache(sc, cacheSize, maxKey);
183
 
 
184
 
    long start = System.currentTimeMillis();
185
 
 
186
 
    Thread[] threads = new Thread[nThreads];
187
 
    final AtomicInteger puts = new AtomicInteger(0);
188
 
    for (int i=0; i<threads.length; i++) {
189
 
      final int seed=random.nextInt();
190
 
      threads[i] = new Thread() {
191
 
        @Override
192
 
        public void run() {
193
 
          int ret = useCache(sc, numGets/nThreads, maxKey, seed);
194
 
          puts.addAndGet(ret);
195
 
        }
196
 
      };
197
 
    }
198
 
 
199
 
    for (Thread thread : threads) {
200
 
      try {
201
 
        thread.start();
202
 
      } catch (Exception e) {
203
 
        e.printStackTrace();
204
 
      }
205
 
    }
206
 
 
207
 
    for (Thread thread : threads) {
208
 
      try {
209
 
        thread.join();
210
 
      } catch (Exception e) {
211
 
        e.printStackTrace();
212
 
      }
213
 
    }
214
 
 
215
 
    long end = System.currentTimeMillis();
216
 
    System.out.println("time=" + (end-start) + " impl=" +sc.getClass().getSimpleName()
217
 
            +" nThreads= " + nThreads + " size="+cacheSize+" maxKey="+maxKey+" gets="+numGets
218
 
            +" hitRatio="+(1-(((double)puts.get())/numGets)));
219
 
  }
220
 
 
221
 
  void perfTestBoth(int nThreads, int numGets, int cacheSize, int maxKey) {
222
 
    cachePerfTest(new LRUCache(), nThreads, numGets, cacheSize, maxKey);
223
 
    cachePerfTest(new FastLRUCache(), nThreads, numGets, cacheSize, maxKey);
224
 
  }
225
 
 
226
 
  /***
227
 
  public void testCachePerf() {
228
 
    // warmup
229
 
    perfTestBoth(2, 100000, 100000, 120000);
230
 
    perfTestBoth(1, 2000000, 100000, 100000); // big cache, 100% hit ratio
231
 
    perfTestBoth(2, 2000000, 100000, 100000); // big cache, 100% hit ratio
232
 
    perfTestBoth(1, 2000000, 100000, 120000); // big cache, bigger hit ratio
233
 
    perfTestBoth(2, 2000000, 100000, 120000); // big cache, bigger hit ratio
234
 
    perfTestBoth(1, 2000000, 100000, 200000); // big cache, ~50% hit ratio
235
 
    perfTestBoth(2, 2000000, 100000, 200000); // big cache, ~50% hit ratio
236
 
    perfTestBoth(1, 2000000, 100000, 1000000); // big cache, ~10% hit ratio
237
 
    perfTestBoth(2, 2000000, 100000, 1000000); // big cache, ~10% hit ratio
238
 
 
239
 
    perfTestBoth(1, 2000000, 1000, 1000); // small cache, ~100% hit ratio
240
 
    perfTestBoth(2, 2000000, 1000, 1000); // small cache, ~100% hit ratio
241
 
    perfTestBoth(1, 2000000, 1000, 1200); // small cache, bigger hit ratio
242
 
    perfTestBoth(2, 2000000, 1000, 1200); // small cache, bigger hit ratio
243
 
    perfTestBoth(1, 2000000, 1000, 2000); // small cache, ~50% hit ratio
244
 
    perfTestBoth(2, 2000000, 1000, 2000); // small cache, ~50% hit ratio
245
 
    perfTestBoth(1, 2000000, 1000, 10000); // small cache, ~10% hit ratio
246
 
    perfTestBoth(2, 2000000, 1000, 10000); // small cache, ~10% hit ratio
247
 
  }
248
 
  ***/
249
 
 
250
 
 
251
 
}