pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / backwards / src / test / org / apache / lucene / util / TestDoubleBarrelLRUCache.java
1 package org.apache.lucene.util;
2
3 /**
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements.  See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License.  You may obtain a copy of the License at
10 *
11 *     http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 import org.apache.lucene.util.LuceneTestCase;
21
22 public class TestDoubleBarrelLRUCache extends LuceneTestCase {
23
24   private void testCache(DoubleBarrelLRUCache<CloneableInteger,Object> cache, int n) throws Exception {
25     Object dummy = new Object();
26     
27     for (int i = 0; i < n; i++) {
28       cache.put(new CloneableInteger(i), dummy);
29     }
30     
31     // access every 2nd item in cache
32     for (int i = 0; i < n; i+=2) {
33       assertNotNull(cache.get(new CloneableInteger(i)));
34     }
35     
36     // add n/2 elements to cache, the ones that weren't
37     // touched in the previous loop should now be thrown away
38     for (int i = n; i < n + (n / 2); i++) {
39       cache.put(new CloneableInteger(i), dummy);
40     }
41     
42     // access every 4th item in cache
43     for (int i = 0; i < n; i+=4) {
44       assertNotNull(cache.get(new CloneableInteger(i)));
45     }
46
47     // add 3/4n elements to cache, the ones that weren't
48     // touched in the previous loops should now be thrown away
49     for (int i = n; i < n + (n * 3 / 4); i++) {
50       cache.put(new CloneableInteger(i), dummy);
51     }
52     
53     // access every 4th item in cache
54     for (int i = 0; i < n; i+=4) {
55       assertNotNull(cache.get(new CloneableInteger(i)));
56     }
57   }
58     
59   public void testLRUCache() throws Exception {
60     final int n = 100;
61     testCache(new DoubleBarrelLRUCache<CloneableInteger,Object>(n), n);
62   }
63
64   private class CacheThread extends Thread {
65     private final CloneableObject[] objs;
66     private final DoubleBarrelLRUCache<CloneableObject,Object> c;
67     private final long endTime;
68     volatile boolean failed;
69
70     public CacheThread(DoubleBarrelLRUCache<CloneableObject,Object> c,
71                        CloneableObject[] objs, long endTime) {
72       this.c = c;
73       this.objs = objs;
74       this.endTime = endTime;
75     }
76
77     @Override
78     public void run() {
79       try {
80         long count = 0;
81         long miss = 0;
82         long hit = 0;
83         final int limit = objs.length;
84
85         while(true) {
86           final CloneableObject obj = objs[(int) ((count/2) % limit)];
87           Object v = c.get(obj);
88           if (v == null) {
89             c.put(new CloneableObject(obj), obj);
90             miss++;
91           } else {
92             assert obj == v;
93             hit++;
94           }
95           if ((++count % 10000) == 0) {
96             if (System.currentTimeMillis() >= endTime)  {
97               break;
98             }
99           }
100         }
101
102         addResults(miss, hit);
103       } catch (Throwable t) {
104         failed = true;
105         throw new RuntimeException(t);
106       }
107     }
108   }
109
110   long totMiss, totHit;
111   void addResults(long miss, long hit) {
112     totMiss += miss;
113     totHit += hit;
114   }
115
116   public void testThreadCorrectness() throws Exception {
117     final int NUM_THREADS = 4;
118     final int CACHE_SIZE = 512;
119     final int OBJ_COUNT = 3*CACHE_SIZE;
120
121     DoubleBarrelLRUCache<CloneableObject,Object> c = new DoubleBarrelLRUCache<CloneableObject,Object>(1024);
122
123     CloneableObject[] objs = new CloneableObject[OBJ_COUNT];
124     for(int i=0;i<OBJ_COUNT;i++) {
125       objs[i] = new CloneableObject(new Object());
126     }
127     
128     final CacheThread[] threads = new CacheThread[NUM_THREADS];
129     final long endTime = System.currentTimeMillis()+1000L;
130     for(int i=0;i<NUM_THREADS;i++) {
131       threads[i] = new CacheThread(c, objs, endTime);
132       threads[i].start();
133     }
134     for(int i=0;i<NUM_THREADS;i++) {
135       threads[i].join();
136       assert !threads[i].failed;
137     }
138     //System.out.println("hits=" + totHit + " misses=" + totMiss);
139   }
140   
141   private static class CloneableObject extends DoubleBarrelLRUCache.CloneableKey {
142     private Object value;
143
144     public CloneableObject(Object value) {
145       this.value = value;
146     }
147
148     @Override
149     public boolean equals(Object other) {
150       return this.value.equals(((CloneableObject) other).value);
151     }
152
153     @Override
154     public int hashCode() {
155       return value.hashCode();
156     }
157
158     @Override
159     public Object clone() {
160       return new CloneableObject(value);
161     }
162   }
163
164   protected static class CloneableInteger extends DoubleBarrelLRUCache.CloneableKey {
165     private Integer value;
166
167     public CloneableInteger(Integer value) {
168       this.value = value;
169     }
170
171     @Override
172     public boolean equals(Object other) {
173       return this.value.equals(((CloneableInteger) other).value);
174     }
175
176     @Override
177     public int hashCode() {
178       return value.hashCode();
179     }
180
181     @Override
182     public Object clone() {
183       return new CloneableInteger(value);
184     }
185   }
186
187
188 }