xref: /AOO41X/main/jurt/com/sun/star/lib/uno/protocols/urp/Cache.java (revision 2be432768a66cc90838f6a32e76ec156f587e741)
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