]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.browsing.ui.common/src/org/simantics/browsing/ui/common/internal/GECache.java
Merge commit '876ede6'
[simantics/platform.git] / bundles / org.simantics.browsing.ui.common / src / org / simantics / browsing / ui / common / internal / GECache.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.browsing.ui.common.internal;\r
13 \r
14 import gnu.trove.map.hash.THashMap;\r
15 import gnu.trove.map.hash.TObjectIntHashMap;\r
16 import gnu.trove.set.hash.THashSet;\r
17 \r
18 import java.util.Collections;\r
19 import java.util.Map;\r
20 import java.util.Set;\r
21 \r
22 import org.simantics.browsing.ui.NodeContext;\r
23 import org.simantics.browsing.ui.NodeContext.CacheKey;\r
24 \r
25 public class GECache implements IGECache {\r
26 \r
27     final Map<GECacheKey, IGECacheEntry> entries = new THashMap<GECacheKey, IGECacheEntry>();\r
28     final Map<GECacheKey, Set<UIElementReference>> treeReferences = new THashMap<GECacheKey, Set<UIElementReference>>();\r
29 \r
30     final private static class GECacheKey {\r
31 \r
32         private NodeContext context;\r
33         private CacheKey<?> key;\r
34 \r
35         GECacheKey(NodeContext context, CacheKey<?> key) {\r
36             this.context = context;\r
37             this.key = key;\r
38             if (context == null || key == null) \r
39                 throw new IllegalArgumentException("Null context or key is not accepted");\r
40         }\r
41 \r
42         GECacheKey(GECacheKey other) {\r
43             this.context = other.context;\r
44             this.key = other.key;\r
45             if (context == null || key == null) \r
46                 throw new IllegalArgumentException("Null context or key is not accepted");\r
47         }\r
48 \r
49         void setValues(NodeContext context, CacheKey<?> key) {\r
50             this.context = context;\r
51             this.key = key;\r
52             if (context == null || key == null) \r
53                 throw new IllegalArgumentException("Null context or key is not accepted");\r
54         }\r
55 \r
56         @Override\r
57         public int hashCode() {\r
58             return context.hashCode() | key.hashCode();\r
59         }\r
60 \r
61         @Override\r
62         public boolean equals(Object object) {\r
63 \r
64             if (this == object)\r
65                 return true;\r
66             else if (object == null)\r
67                 return false;\r
68 //            else if (getClass() != object.getClass())\r
69 //                return false;\r
70 \r
71             GECacheKey i = (GECacheKey)object;\r
72 \r
73             return key.equals(i.key) && context.equals(i.context);\r
74 \r
75         }\r
76 \r
77     };\r
78 \r
79     /**\r
80      * This single instance is used for all get operations from the cache. This\r
81      * should work since the GE cache is meant to be single-threaded within the\r
82      * current UI thread, what ever that thread is. For put operations which\r
83      * store the key, this is not used.\r
84      */\r
85     NodeContext getNC = new NodeContext() {\r
86                 @Override\r
87         public <T> T getAdapter(Class<T> adapter) {\r
88                 return null;\r
89         }\r
90         \r
91         @Override\r
92         public <T> T getConstant(ConstantKey<T> key) {\r
93                 return null;\r
94         }\r
95         \r
96         @Override\r
97         public Set<ConstantKey<?>> getKeys() {\r
98                 return Collections.emptySet();\r
99         }\r
100     };\r
101     CacheKey<?> getCK = new CacheKey<Object>() {\r
102         @Override\r
103         public Object processorIdenfitier() {\r
104                 return this;\r
105         }\r
106         };\r
107     GECacheKey getKey = new GECacheKey(getNC, getCK);\r
108 \r
109     public <T> IGECacheEntry put(NodeContext context, CacheKey<T> key, T value) {\r
110         IGECacheEntry entry = new GECacheEntry(context, key, value);\r
111         entries.put(new GECacheKey(context, key), entry);\r
112         return entry;\r
113     }\r
114 \r
115     @SuppressWarnings("unchecked")\r
116     public <T> T get(NodeContext context, CacheKey<T> key) {\r
117         getKey.setValues(context, key);\r
118         IGECacheEntry entry = entries.get(getKey);\r
119         if (entry == null)\r
120             return null;\r
121         return (T) entry.getValue();\r
122     }\r
123 \r
124     @Override\r
125     public <T> IGECacheEntry getEntry(NodeContext context, CacheKey<T> key) {\r
126         assert(context != null);\r
127         assert(key != null);\r
128         getKey.setValues(context, key);\r
129         return entries.get(getKey);\r
130     }\r
131 \r
132     @Override\r
133     public <T> void remove(NodeContext context, CacheKey<T> key) {\r
134         getKey.setValues(context, key);\r
135         entries.remove(getKey);\r
136     }\r
137 \r
138     @Override\r
139     public <T> Set<UIElementReference> getTreeReference(NodeContext context, CacheKey<T> key) {\r
140         assert(context != null);\r
141         assert(key != null);\r
142         getKey.setValues(context, key);\r
143         return treeReferences.get(getKey);\r
144     }\r
145 \r
146     @Override\r
147     public <T> void putTreeReference(NodeContext context, CacheKey<T> key, UIElementReference reference) {\r
148         assert(context != null);\r
149         assert(key != null);\r
150         getKey.setValues(context, key);\r
151         Set<UIElementReference> refs = treeReferences.get(getKey);\r
152         if (refs != null) {\r
153             refs.add(reference);\r
154         } else {\r
155             refs = new THashSet<UIElementReference>(4);\r
156             refs.add(reference);\r
157             treeReferences.put(new GECacheKey(getKey), refs);\r
158         }\r
159     }\r
160 \r
161     @Override\r
162     public <T> Set<UIElementReference> removeTreeReference(NodeContext context, CacheKey<T> key) {\r
163         assert(context != null);\r
164         assert(key != null);\r
165         getKey.setValues(context, key);\r
166         return treeReferences.remove(getKey);\r
167     }\r
168     \r
169     @Override\r
170     public boolean isShown(NodeContext context) {\r
171         return references.get(context) > 0;\r
172     }\r
173 \r
174     private TObjectIntHashMap<NodeContext> references = new TObjectIntHashMap<NodeContext>();\r
175     \r
176     @Override\r
177     public void incRef(NodeContext context) {\r
178         int exist = references.get(context);\r
179         references.put(context, exist+1);\r
180     }\r
181     \r
182     @Override\r
183     public void decRef(NodeContext context) {\r
184         int exist = references.get(context);\r
185         references.put(context, exist-1);\r
186         if(exist == 1) {\r
187                 references.remove(context);\r
188         }\r
189     }\r
190     \r
191     public void dispose() {\r
192         references.clear();\r
193         entries.clear();\r
194         treeReferences.clear();\r
195     }\r
196     \r
197 }\r