]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterSupport2.java
Merge commit 'b809a171b6dfb81ed9ef9e84870dcbcbc5912f0e'
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / internal / ClusterSupport2.java
1 package org.simantics.acorn.internal;
2
3 import java.io.ByteArrayInputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.util.concurrent.locks.ReentrantReadWriteLock;
7 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
8 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
9
10 import org.simantics.acorn.ClusterManager;
11 import org.simantics.db.Session;
12 import org.simantics.db.exception.DatabaseException;
13 import org.simantics.db.impl.ClusterBase;
14 import org.simantics.db.impl.ClusterI;
15 import org.simantics.db.impl.ClusterSupport;
16 import org.simantics.db.impl.IClusterTable;
17 import org.simantics.db.service.ClusterUID;
18
19 import gnu.trove.map.hash.TIntObjectHashMap;
20
21 public class ClusterSupport2 implements ClusterSupport, IClusterTable {
22         
23         final private static boolean DEBUG = false;
24
25         public ClusterManager impl;
26         
27         public TIntObjectHashMap<ClusterUID> uidCache = new TIntObjectHashMap<ClusterUID>(); 
28         
29         public ClusterSupport2(ClusterManager impl) {
30                 this.impl = impl;
31         }
32         
33         @Override
34         public int createClusterKeyByClusterUID(ClusterUID clusterUID, long clusterId) {
35                 throw new UnsupportedOperationException();
36         }
37
38         @Override
39         public ClusterBase getClusterByClusterUIDOrMake(ClusterUID clusterUID) {
40                 try {
41             return impl.getClusterByClusterUIDOrMake(clusterUID);
42         } catch (DatabaseException e) {
43             e.printStackTrace();
44             return null;
45         }
46         }
47
48         @Override
49         public ClusterBase getClusterByClusterId(long clusterId) {
50                 throw new UnsupportedOperationException();
51         }
52
53         @Override
54         public ClusterBase getClusterByClusterKey(int clusterKey) {
55                 throw new UnsupportedOperationException();
56         }
57
58         ReentrantReadWriteLock uidLock = new ReentrantReadWriteLock();
59         ReadLock uidRead = uidLock.readLock();
60         WriteLock uidWrite = uidLock.writeLock();
61         
62         @Override
63         public ClusterUID getClusterUIDByResourceKey(int resourceKey) throws DatabaseException {
64
65                 ClusterUID cuid;
66                 
67                 uidRead.lock();
68                 cuid = uidCache.get(resourceKey >> 12);
69                 uidRead.unlock();
70                 if(cuid != null) return cuid;
71                 uidWrite.lock();
72                 cuid = uidCache.get(resourceKey >> 12);
73                 if(cuid == null) {
74                         cuid = impl.getClusterUIDByResourceKeyWithoutMutex(resourceKey); 
75                         uidCache.put(resourceKey >> 12, cuid);
76                 }
77                 uidWrite.unlock();
78                 
79                 return cuid;
80                 
81         }
82         
83         @Override
84         public int getClusterKeyByClusterUIDOrMake(ClusterUID clusterUID) {
85                 return impl.getClusterKeyByClusterUIDOrMakeWithoutMutex(clusterUID);
86         }
87         
88     @Override
89     public int getClusterKeyByClusterUIDOrMake(long id1, long id2) {
90                 throw new UnsupportedOperationException();
91     }
92
93         @Override
94         public ClusterBase getClusterByResourceKey(int resourceKey) {
95                 throw new UnsupportedOperationException();
96 //              return impl.getClusterByResourceKey(resourceKey);
97         }
98
99         @Override
100         public long getClusterIdOrCreate(ClusterUID clusterUID) {
101                 return impl.getClusterIdOrCreate(clusterUID);
102         }
103
104         @Override
105         public void addStatement(Object cluster) {
106                 // nop
107         }
108
109         @Override
110         public void cancelStatement(Object cluster) {
111                 // nop
112         }
113
114         @Override
115         public void removeStatement(Object cluster) {
116                 // nop
117         }
118
119         @Override
120         public void removeValue(Object cluster) {
121                 // nop
122         }
123
124         @Override
125         public void setImmutable(Object cluster, boolean immutable) {
126                 // nop
127         }
128
129         @Override
130         public void setDeleted(Object cluster, boolean deleted) {
131                 // TODO Auto-generated method stub
132                 
133         }
134
135         
136         
137         @Override
138         public void cancelValue(Object cluster) {
139                 throw new UnsupportedOperationException();
140         }
141
142         @Override
143         public void setValue(Object cluster, long clusterId, byte[] bytes,
144                         int length) {
145                 // nop
146         }
147
148         @Override
149         public void modiValue(Object _cluster, long clusterId, long voffset,
150                         int length, byte[] bytes, int offset) {
151                 // nop
152         }
153
154         @Override
155         public void createResource(Object cluster, short resourceIndex,
156                         long clusterId) {
157                 // No op
158         }
159
160         @Override
161         public void addStatementIndex(Object cluster, int resourceKey,
162                         ClusterUID clusterUID, byte op) {
163                 // No op
164         }
165
166         @Override
167         public void setStreamOff(boolean setOff) {
168                 throw new UnsupportedOperationException();
169         }
170
171         @Override
172         public boolean getStreamOff() {
173                 return true;
174         }
175
176         
177     private static class ResourceSegment {
178         public long   valueSize;
179
180         public byte[] bytes;
181
182         ResourceSegment(long valueSize, byte[] bytes) {
183             this.valueSize = valueSize;
184             this.bytes = bytes;
185         }
186     }
187
188     public ResourceSegment getResourceSegment(int resourceIndex, ClusterUID clusterUID, long offset, short size)
189     throws DatabaseException {
190         if (DEBUG)
191             System.out.println("DEBUG: getResourceSegment ri=" + resourceIndex + " cid=" + clusterUID + " offset=" + offset + " size=" + size);
192         
193         org.simantics.db.Database.Session.ResourceSegment t = impl.getResourceSegment(clusterUID.asBytes(), resourceIndex, offset, size);
194         return new ResourceSegment(t.getValueSize(), t.getSegment());
195         
196     }
197     
198     protected byte[] getValueBig(ClusterBase cluster, int resourceIndex, int offset, int length) throws DatabaseException {
199     
200         assert(offset == 0);
201         assert(length == 0);
202         
203         ClusterUID clusterUID = cluster.clusterUID;
204         
205         return impl.getResourceFile(clusterUID.asBytes(), resourceIndex);
206         
207     }
208
209     protected InputStream getValueStreamBig(ClusterBase cluster, final int resourceIndex, int offset, int length) throws DatabaseException {
210
211         final ClusterUID clusterUID = cluster.clusterUID;
212         
213         if (DEBUG)
214                 System.out.println("DEBUG: getResourceFile ri=" + resourceIndex + " cid=" + clusterUID + " off=" + offset + " len=" + length);
215         final int IMAX = 0xFFFF;
216         short slen = (short)Math.min(length != 0 ? length : IMAX, IMAX);
217         final ResourceSegment s = getResourceSegment(resourceIndex, clusterUID, offset, slen);
218         if (s.valueSize < 0)
219                 throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
220                                 " cluster=" + clusterUID + " off=" + offset + " len=" + length + " (1).");
221         int ilen = (int)slen & 0xFFFF;
222         assert(s.bytes.length <= ilen);
223         if (0 == length) {
224                 if (s.valueSize > Integer.MAX_VALUE)
225                         throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
226                                         " cluster=" + clusterUID + " off=" + offset + " len=" + length +
227                                         ". Value size=" + s.valueSize + " (2).");
228                 length = (int)s.valueSize;
229         }
230         long rSize = s.valueSize - offset;
231         if (rSize < length)
232                 throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
233                                 " cluster=" + clusterUID + " off=" + offset + " len=" + length +
234                                 ". Value size=" + s.valueSize + " (3).");
235         else if (length <= IMAX)
236                 return new ByteArrayInputStream(s.bytes);
237
238         final int finalLength = length;
239
240         return new InputStream() {
241
242                 int left = finalLength;
243                 long valueOffset = 0;
244                 int offset = 0;
245                 ResourceSegment _s = s;
246
247                 @Override
248                 public int read() throws IOException {
249
250                         if(left <= 0) throw new IllegalStateException();
251
252                         if(offset == _s.bytes.length) {
253                                 short slen = (short)Math.min(left, IMAX);
254                                 valueOffset += _s.bytes.length;
255                                 try {
256                                         _s = getResourceSegment(resourceIndex, clusterUID, valueOffset, slen);
257                                 } catch (DatabaseException e) {
258                                         throw new IOException(e);
259                                 }
260                                 offset = 0;
261                         }
262
263                         left--;
264                         int result = _s.bytes[offset++];
265                         if(result < 0) result += 256;
266                         return result;
267
268                 }
269
270         };
271
272     }
273         
274         @Override
275         public InputStream getValueStreamEx(int resourceIndex, long clusterId)
276                         throws DatabaseException {
277                 ClusterBase cluster = impl.getClusterByClusterUIDOrMakeProxy(ClusterUID.make(0, clusterId));
278                 return getValueStreamBig(cluster, resourceIndex, 0, 0);
279         }
280
281         @Override
282         public byte[] getValueEx(int resourceIndex, long clusterId)
283                         throws DatabaseException {
284                 ClusterBase cluster = impl.getClusterByClusterUIDOrMakeProxy(ClusterUID.make(0, clusterId));
285                 return getValueBig(cluster, resourceIndex, 0, 0);
286         }
287
288         @Override
289         public byte[] getValueEx(int resourceIndex, long clusterId, long voffset,
290                         int length) throws DatabaseException {
291                 throw new UnsupportedOperationException();
292         }
293
294         @Override
295         public long getValueSizeEx(int resourceIndex, long clusterId)
296                         throws DatabaseException {
297                 throw new UnsupportedOperationException();
298         }
299
300         @Override
301         public int wait4RequestsLess(int limit) throws DatabaseException {
302                 throw new UnsupportedOperationException();
303         }
304
305         @Override
306         public Session getSession() {
307                 return null;
308         }
309
310         @Override
311         public IClusterTable getClusterTable() {
312                 return this;
313         }
314
315         @Override
316         public <T extends ClusterI> T getClusterByClusterUIDOrMakeProxy(ClusterUID clusterUID) {
317                 try {
318             return (T)impl.getClusterByClusterUIDOrMakeProxy(clusterUID);
319         } catch (DatabaseException e) {
320             e.printStackTrace();
321             return null;
322         }
323         }
324
325         @Override
326         public <T extends ClusterI> T getClusterProxyByResourceKey(int resourceKey) {
327                 try {
328             return impl.getClusterProxyByResourceKey(resourceKey);
329         } catch (DatabaseException e) {
330             e.printStackTrace();
331             return null;
332         }
333         }
334
335         @Override
336         public int getClusterKeyByUID(long id1, long id2) throws DatabaseException {
337                 return impl.getClusterKeyByUID(id1, id2);
338         }
339
340 }