1*2be43276SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*2be43276SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*2be43276SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*2be43276SAndrew Rist * distributed with this work for additional information 6*2be43276SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*2be43276SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*2be43276SAndrew Rist * "License"); you may not use this file except in compliance 9*2be43276SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*2be43276SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*2be43276SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*2be43276SAndrew Rist * software distributed under the License is distributed on an 15*2be43276SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*2be43276SAndrew Rist * KIND, either express or implied. See the License for the 17*2be43276SAndrew Rist * specific language governing permissions and limitations 18*2be43276SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*2be43276SAndrew Rist *************************************************************/ 21*2be43276SAndrew Rist 22*2be43276SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir package com.sun.star.lib.uno.protocols.urp; 25cdf0e10cSrcweir 26cdf0e10cSrcweir import java.util.HashMap; 27cdf0e10cSrcweir 28cdf0e10cSrcweir /** 29cdf0e10cSrcweir An LRU cache for arbitrary objects. 30cdf0e10cSrcweir 31cdf0e10cSrcweir This class is not synchronized, as any necessary synchronization will already 32cdf0e10cSrcweir take place in the client. 33cdf0e10cSrcweir */ 34cdf0e10cSrcweir final class Cache { 35cdf0e10cSrcweir /** 36cdf0e10cSrcweir Create a cache. 37cdf0e10cSrcweir 38cdf0e10cSrcweir @param size the maximum cache size, must be between 0, inclusive, and 39cdf0e10cSrcweir NOT_CACHED, exclusive 40cdf0e10cSrcweir */ Cache(int size)41cdf0e10cSrcweir public Cache(int size) { 42cdf0e10cSrcweir maxSize = size; 43cdf0e10cSrcweir } 44cdf0e10cSrcweir add(boolean[] found, Object content)45cdf0e10cSrcweir public int add(boolean[] found, Object content) { 46cdf0e10cSrcweir Entry e = (Entry) map.get(content); 47cdf0e10cSrcweir found[0] = e != null; 48cdf0e10cSrcweir if (e == null) { 49cdf0e10cSrcweir if (map.size() < maxSize) { 50cdf0e10cSrcweir // There is still room for a new entry at the front: 51cdf0e10cSrcweir e = new Entry(content, map.size(), null, first); 52cdf0e10cSrcweir if (first == null) { 53cdf0e10cSrcweir last = e; 54cdf0e10cSrcweir } else { 55cdf0e10cSrcweir first.prev = e; 56cdf0e10cSrcweir } 57cdf0e10cSrcweir first = e; 58cdf0e10cSrcweir } else if (last != null) { 59cdf0e10cSrcweir // Take last entry out and recycle as new front: 60cdf0e10cSrcweir map.remove(last.content); 61cdf0e10cSrcweir e = last; 62cdf0e10cSrcweir e.content = content; 63cdf0e10cSrcweir if (first != last) { 64cdf0e10cSrcweir // Reached only if maxSize > 1: 65cdf0e10cSrcweir last = last.prev; 66cdf0e10cSrcweir last.next = null; 67cdf0e10cSrcweir e.prev = null; 68cdf0e10cSrcweir e.next = first; 69cdf0e10cSrcweir first.prev = e; 70cdf0e10cSrcweir first = e; 71cdf0e10cSrcweir } 72cdf0e10cSrcweir } else { 73cdf0e10cSrcweir // Reached iff maxSize == 0: 74cdf0e10cSrcweir return NOT_CACHED; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir map.put(content, e); 77cdf0e10cSrcweir } else if (e != first) { 78cdf0e10cSrcweir // Move to front (reached only if maxSize > 1): 79cdf0e10cSrcweir e.prev.next = e.next; 80cdf0e10cSrcweir if (e.next == null) { 81cdf0e10cSrcweir last = e.prev; 82cdf0e10cSrcweir } else { 83cdf0e10cSrcweir e.next.prev = e.prev; 84cdf0e10cSrcweir } 85cdf0e10cSrcweir e.prev = null; 86cdf0e10cSrcweir e.next = first; 87cdf0e10cSrcweir first.prev = e; 88cdf0e10cSrcweir first = e; 89cdf0e10cSrcweir } 90cdf0e10cSrcweir return e.index; 91cdf0e10cSrcweir } 92cdf0e10cSrcweir 93cdf0e10cSrcweir public static final int NOT_CACHED = 0xFFFF; 94cdf0e10cSrcweir 95cdf0e10cSrcweir private static final class Entry { Entry(Object content, int index, Entry prev, Entry next)96cdf0e10cSrcweir public Entry(Object content, int index, Entry prev, Entry next) { 97cdf0e10cSrcweir this.content = content; 98cdf0e10cSrcweir this.index = index; 99cdf0e10cSrcweir this.prev = prev; 100cdf0e10cSrcweir this.next = next; 101cdf0e10cSrcweir } 102cdf0e10cSrcweir 103cdf0e10cSrcweir public Object content; 104cdf0e10cSrcweir public int index; 105cdf0e10cSrcweir public Entry prev; 106cdf0e10cSrcweir public Entry next; 107cdf0e10cSrcweir } 108cdf0e10cSrcweir 109cdf0e10cSrcweir // first/last form a list of 0 to maxSize entries, most recently used first; 110cdf0e10cSrcweir // map contains the same entries; each entry has a unique index in the range 111cdf0e10cSrcweir // 0 to maxSize - 1 112cdf0e10cSrcweir private final int maxSize; 113cdf0e10cSrcweir private final HashMap map = new HashMap(); // from Object to Entry 114cdf0e10cSrcweir private Entry first = null; 115cdf0e10cSrcweir private Entry last = null; 116cdf0e10cSrcweir } 117