KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > versant > core > server > CompiledQueryCache


1
2 /*
3  * Copyright (c) 1998 - 2005 Versant Corporation
4  * All rights reserved. This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License v1.0
6  * which accompanies this distribution, and is available at
7  * http://www.eclipse.org/legal/epl-v10.html
8  *
9  * Contributors:
10  * Versant Corporation - initial API and implementation
11  */

12 package com.versant.core.server;
13
14 import com.versant.core.jdo.QueryDetails;
15
16 import java.util.Map JavaDoc;
17 import java.util.HashMap JavaDoc;
18
19 /**
20  * LRU map of QueryDetails -> CompiledQuery. Also assigns a unique ID to
21  * each query added to the cache and supports lookup by this ID.
22  */

23 public final class CompiledQueryCache {
24
25     private final int maxSize;
26     private final Map JavaDoc map = new HashMap JavaDoc(); // QueryDetails -> Entry
27
private final Map JavaDoc idMap = new HashMap JavaDoc(); // Integer ID -> Entry
28
private Entry head, tail;
29     private int lastID;
30
31     private class Entry {
32         CompiledQuery cq;
33         Entry prev, next;
34     }
35
36     public CompiledQueryCache(int maxSize) {
37         this.maxSize = maxSize <= 0 ? 1000 : maxSize;
38     }
39
40     /**
41      * Get the cached CompiledQuery for q or null if none. This will make it
42      * the most recently used query.
43      */

44     public synchronized CompiledQuery get(QueryDetails q) {
45         Entry e = (Entry)map.get(q);
46         if (e == null) {
47             return null;
48         }
49         removeFromLRUList(e);
50         addToHeadOfLRUList(e);
51         return e.cq;
52     }
53
54     /**
55      * Get the cached CompiledQuery for id or null if none. This will make it
56      * the most recently used query.
57      */

58     public synchronized CompiledQuery get(int id) {
59         Entry e = (Entry)idMap.get(new Integer JavaDoc(id));
60         if (e == null) {
61             return null;
62         }
63         removeFromLRUList(e);
64         addToHeadOfLRUList(e);
65         return e.cq;
66     }
67
68     /**
69      * Add cq to the cache. If there is already an entry for cq in the cache
70      * then the current entry is returned and nothing is done. This avoids the
71      * need to synchronize on this cache during query compilation. It is
72      * possible that two threads might compile the same query after discovering
73      * that it is not in cache but this is ok.
74      */

75     public synchronized CompiledQuery add(CompiledQuery cq) {
76         Entry e = (Entry)map.get(cq.getQueryDetails());
77         if (e != null) {
78             return e.cq;
79         }
80         e = new Entry();
81         e.cq = cq;
82         int id = ++lastID;
83         cq.setId(id);
84         map.put(cq.getQueryDetails(), e);
85         idMap.put(new Integer JavaDoc(id), e);
86         addToHeadOfLRUList(e);
87         for (int c = map.size() - maxSize; c > 0; c--) {
88             map.remove(tail.cq.getQueryDetails());
89             idMap.remove(new Integer JavaDoc(tail.cq.getId()));
90             tail.next.prev = null;
91             tail = tail.next;
92         }
93         return cq;
94     }
95
96     /**
97      * Empty the cache.
98      */

99     public synchronized void clear() {
100         map.clear();
101         head = tail = null;
102     }
103
104     /**
105      * Remove e from the double linked LRU list.
106      */

107     private void removeFromLRUList(Entry e) {
108         if (e.prev != null) {
109             e.prev.next = e.next;
110         } else {
111             tail = e.next;
112         }
113         if (e.next != null) {
114             e.next.prev = e.prev;
115         } else {
116             head = e.prev;
117         }
118         e.next = e.prev = null;
119     }
120
121     /**
122      * Add e to the head of the double linked LRU list. This will make it the
123      * most recently accessed object.
124      */

125     private void addToHeadOfLRUList(Entry e) {
126         e.next = null;
127         e.prev = head;
128         if (head != null) {
129             head.next = e;
130         }
131         head = e;
132         if (tail == null) {
133             tail = e;
134         }
135     }
136
137 }
138
139
Popular Tags