1 package org.simantics.acorn.internal;
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;
10 import org.simantics.acorn.ClusterManager;
11 import org.simantics.acorn.exception.AcornAccessVerificationException;
12 import org.simantics.acorn.exception.IllegalAcornStateException;
13 import org.simantics.db.Session;
14 import org.simantics.db.exception.DatabaseException;
15 import org.simantics.db.impl.ClusterBase;
16 import org.simantics.db.impl.ClusterI;
17 import org.simantics.db.impl.ClusterSupport;
18 import org.simantics.db.impl.IClusterTable;
19 import org.simantics.db.service.ClusterUID;
21 import gnu.trove.map.hash.TIntObjectHashMap;
23 public class ClusterSupport2 implements ClusterSupport, IClusterTable {
25 final private static boolean DEBUG = false;
27 public ClusterManager impl;
29 public TIntObjectHashMap<ClusterUID> uidCache = new TIntObjectHashMap<ClusterUID>();
31 public ClusterSupport2(ClusterManager impl) {
36 public int createClusterKeyByClusterUID(ClusterUID clusterUID, long clusterId) {
37 throw new UnsupportedOperationException();
41 public ClusterBase getClusterByClusterUIDOrMake(ClusterUID clusterUID) {
43 return impl.getClusterByClusterUIDOrMake(clusterUID);
44 } catch (DatabaseException e) {
51 public ClusterBase getClusterByClusterId(long clusterId) {
52 throw new UnsupportedOperationException();
56 public ClusterBase getClusterByClusterKey(int clusterKey) {
57 throw new UnsupportedOperationException();
60 ReentrantReadWriteLock uidLock = new ReentrantReadWriteLock();
61 ReadLock uidRead = uidLock.readLock();
62 WriteLock uidWrite = uidLock.writeLock();
65 public ClusterUID getClusterUIDByResourceKey(int resourceKey) throws DatabaseException {
70 cuid = uidCache.get(resourceKey >> 12);
72 if(cuid != null) return cuid;
74 cuid = uidCache.get(resourceKey >> 12);
76 cuid = impl.getClusterUIDByResourceKeyWithoutMutex(resourceKey);
77 uidCache.put(resourceKey >> 12, cuid);
86 public int getClusterKeyByClusterUIDOrMake(ClusterUID clusterUID) {
88 return impl.getClusterKeyByClusterUIDOrMakeWithoutMutex(clusterUID);
89 } catch (IllegalAcornStateException | AcornAccessVerificationException e) {
90 throw new RuntimeException(e);
95 public int getClusterKeyByClusterUIDOrMake(long id1, long id2) {
96 throw new UnsupportedOperationException();
100 public ClusterBase getClusterByResourceKey(int resourceKey) {
101 throw new UnsupportedOperationException();
102 // return impl.getClusterByResourceKey(resourceKey);
106 public long getClusterIdOrCreate(ClusterUID clusterUID) {
107 return impl.getClusterIdOrCreate(clusterUID);
111 public void addStatement(Object cluster) {
116 public void cancelStatement(Object cluster) {
121 public void removeStatement(Object cluster) {
126 public void removeValue(Object cluster) {
131 public void setImmutable(Object cluster, boolean immutable) {
136 public void setDeleted(Object cluster, boolean deleted) {
137 // TODO Auto-generated method stub
144 public void cancelValue(Object cluster) {
145 throw new UnsupportedOperationException();
149 public void setValue(Object cluster, long clusterId, byte[] bytes,
155 public void modiValue(Object _cluster, long clusterId, long voffset,
156 int length, byte[] bytes, int offset) {
161 public void createResource(Object cluster, short resourceIndex,
167 public void addStatementIndex(Object cluster, int resourceKey,
168 ClusterUID clusterUID, byte op) {
173 public void setStreamOff(boolean setOff) {
174 throw new UnsupportedOperationException();
178 public boolean getStreamOff() {
183 private static class ResourceSegment {
184 public long valueSize;
188 ResourceSegment(long valueSize, byte[] bytes) {
189 this.valueSize = valueSize;
194 public ResourceSegment getResourceSegment(int resourceIndex, ClusterUID clusterUID, long offset, short size) throws DatabaseException {
196 System.out.println("DEBUG: getResourceSegment ri=" + resourceIndex + " cid=" + clusterUID + " offset=" + offset + " size=" + size);
199 org.simantics.db.Database.Session.ResourceSegment t = impl.getResourceSegment(clusterUID.asBytes(), resourceIndex, offset, size);
200 return new ResourceSegment(t.getValueSize(), t.getSegment());
201 } catch (AcornAccessVerificationException | IllegalAcornStateException e) {
202 throw new DatabaseException(e);
206 protected byte[] getValueBig(ClusterBase cluster, int resourceIndex, int offset, int length) throws DatabaseException {
211 ClusterUID clusterUID = cluster.clusterUID;
214 return impl.getResourceFile(clusterUID.asBytes(), resourceIndex);
215 } catch (AcornAccessVerificationException | IllegalAcornStateException e) {
216 throw new DatabaseException(e);
220 protected InputStream getValueStreamBig(ClusterBase cluster, final int resourceIndex, int offset, int length) throws DatabaseException {
222 final ClusterUID clusterUID = cluster.clusterUID;
225 System.out.println("DEBUG: getResourceFile ri=" + resourceIndex + " cid=" + clusterUID + " off=" + offset + " len=" + length);
226 final int IMAX = 0xFFFF;
227 short slen = (short)Math.min(length != 0 ? length : IMAX, IMAX);
228 final ResourceSegment s = getResourceSegment(resourceIndex, clusterUID, offset, slen);
230 throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
231 " cluster=" + clusterUID + " off=" + offset + " len=" + length + " (1).");
232 int ilen = (int)slen & 0xFFFF;
233 assert(s.bytes.length <= ilen);
235 if (s.valueSize > Integer.MAX_VALUE)
236 throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
237 " cluster=" + clusterUID + " off=" + offset + " len=" + length +
238 ". Value size=" + s.valueSize + " (2).");
239 length = (int)s.valueSize;
241 long rSize = s.valueSize - offset;
243 throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
244 " cluster=" + clusterUID + " off=" + offset + " len=" + length +
245 ". Value size=" + s.valueSize + " (3).");
246 else if (length <= IMAX)
247 return new ByteArrayInputStream(s.bytes);
249 final int finalLength = length;
251 return new InputStream() {
253 int left = finalLength;
254 long valueOffset = 0;
256 ResourceSegment _s = s;
259 public int read() throws IOException {
261 if(left <= 0) return -1;
263 if(offset == _s.bytes.length) {
264 short slen = (short)Math.min(left, IMAX);
265 valueOffset += _s.bytes.length;
267 _s = getResourceSegment(resourceIndex, clusterUID, valueOffset, slen);
268 } catch (DatabaseException e) {
269 throw new IOException(e);
275 int result = _s.bytes[offset++];
276 if(result < 0) result += 256;
286 public InputStream getValueStreamEx(int resourceIndex, long clusterId)
287 throws DatabaseException {
288 ClusterBase cluster = impl.getClusterByClusterUIDOrMakeProxy(ClusterUID.make(0, clusterId));
289 return getValueStreamBig(cluster, resourceIndex, 0, 0);
293 public byte[] getValueEx(int resourceIndex, long clusterId)
294 throws DatabaseException {
295 ClusterBase cluster = impl.getClusterByClusterUIDOrMakeProxy(ClusterUID.make(0, clusterId));
296 return getValueBig(cluster, resourceIndex, 0, 0);
300 public byte[] getValueEx(int resourceIndex, long clusterId, long voffset,
301 int length) throws DatabaseException {
302 throw new UnsupportedOperationException();
306 public long getValueSizeEx(int resourceIndex, long clusterId)
307 throws DatabaseException {
308 throw new UnsupportedOperationException();
312 public int wait4RequestsLess(int limit) throws DatabaseException {
313 throw new UnsupportedOperationException();
317 public Session getSession() {
322 public IClusterTable getClusterTable() {
327 public <T extends ClusterI> T getClusterByClusterUIDOrMakeProxy(ClusterUID clusterUID) {
329 return (T)impl.getClusterByClusterUIDOrMakeProxy(clusterUID);
330 } catch (DatabaseException e) {
337 public <T extends ClusterI> T getClusterProxyByResourceKey(int resourceKey) {
339 return impl.getClusterProxyByResourceKey(resourceKey);
340 } catch (DatabaseException e) {
347 public int getClusterKeyByUID(long id1, long id2) throws DatabaseException {
348 return impl.getClusterKeyByUID(id1, id2);