1 package org.apache.lucene.util;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
20 import org.apache.lucene.util.LuceneTestCase;
22 public class TestDoubleBarrelLRUCache extends LuceneTestCase {
24 private void testCache(DoubleBarrelLRUCache<CloneableInteger,Object> cache, int n) throws Exception {
25 Object dummy = new Object();
27 for (int i = 0; i < n; i++) {
28 cache.put(new CloneableInteger(i), dummy);
31 // access every 2nd item in cache
32 for (int i = 0; i < n; i+=2) {
33 assertNotNull(cache.get(new CloneableInteger(i)));
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);
42 // access every 4th item in cache
43 for (int i = 0; i < n; i+=4) {
44 assertNotNull(cache.get(new CloneableInteger(i)));
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);
53 // access every 4th item in cache
54 for (int i = 0; i < n; i+=4) {
55 assertNotNull(cache.get(new CloneableInteger(i)));
59 public void testLRUCache() throws Exception {
61 testCache(new DoubleBarrelLRUCache<CloneableInteger,Object>(n), n);
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;
70 public CacheThread(DoubleBarrelLRUCache<CloneableObject,Object> c,
71 CloneableObject[] objs, long endTime) {
74 this.endTime = endTime;
83 final int limit = objs.length;
86 final CloneableObject obj = objs[(int) ((count/2) % limit)];
87 Object v = c.get(obj);
89 c.put(new CloneableObject(obj), obj);
95 if ((++count % 10000) == 0) {
96 if (System.currentTimeMillis() >= endTime) {
102 addResults(miss, hit);
103 } catch (Throwable t) {
105 throw new RuntimeException(t);
110 long totMiss, totHit;
111 void addResults(long miss, long hit) {
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;
121 DoubleBarrelLRUCache<CloneableObject,Object> c = new DoubleBarrelLRUCache<CloneableObject,Object>(1024);
123 CloneableObject[] objs = new CloneableObject[OBJ_COUNT];
124 for(int i=0;i<OBJ_COUNT;i++) {
125 objs[i] = new CloneableObject(new Object());
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);
134 for(int i=0;i<NUM_THREADS;i++) {
136 assert !threads[i].failed;
138 //System.out.println("hits=" + totHit + " misses=" + totMiss);
141 private static class CloneableObject extends DoubleBarrelLRUCache.CloneableKey {
142 private Object value;
144 public CloneableObject(Object value) {
149 public boolean equals(Object other) {
150 return this.value.equals(((CloneableObject) other).value);
154 public int hashCode() {
155 return value.hashCode();
159 public Object clone() {
160 return new CloneableObject(value);
164 protected static class CloneableInteger extends DoubleBarrelLRUCache.CloneableKey {
165 private Integer value;
167 public CloneableInteger(Integer value) {
172 public boolean equals(Object other) {
173 return this.value.equals(((CloneableInteger) other).value);
177 public int hashCode() {
178 return value.hashCode();
182 public Object clone() {
183 return new CloneableInteger(value);