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.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;
19 import gnu.trove.map.hash.TIntObjectHashMap;
21 public class ClusterSupport2 implements ClusterSupport, IClusterTable {
23 final private static boolean DEBUG = false;
25 public ClusterManager impl;
27 public TIntObjectHashMap<ClusterUID> uidCache = new TIntObjectHashMap<ClusterUID>();
29 public ClusterSupport2(ClusterManager impl) {
34 public int createClusterKeyByClusterUID(ClusterUID clusterUID, long clusterId) {
35 throw new UnsupportedOperationException();
39 public ClusterBase getClusterByClusterUIDOrMake(ClusterUID clusterUID) {
41 return impl.getClusterByClusterUIDOrMake(clusterUID);
42 } catch (DatabaseException e) {
49 public ClusterBase getClusterByClusterId(long clusterId) {
50 throw new UnsupportedOperationException();
54 public ClusterBase getClusterByClusterKey(int clusterKey) {
55 throw new UnsupportedOperationException();
58 ReentrantReadWriteLock uidLock = new ReentrantReadWriteLock();
59 ReadLock uidRead = uidLock.readLock();
60 WriteLock uidWrite = uidLock.writeLock();
63 public ClusterUID getClusterUIDByResourceKey(int resourceKey) throws DatabaseException {
68 cuid = uidCache.get(resourceKey >> 12);
70 if(cuid != null) return cuid;
72 cuid = uidCache.get(resourceKey >> 12);
74 cuid = impl.getClusterUIDByResourceKeyWithoutMutex(resourceKey);
75 uidCache.put(resourceKey >> 12, cuid);
84 public int getClusterKeyByClusterUIDOrMake(ClusterUID clusterUID) {
85 return impl.getClusterKeyByClusterUIDOrMakeWithoutMutex(clusterUID);
89 public int getClusterKeyByClusterUIDOrMake(long id1, long id2) {
90 throw new UnsupportedOperationException();
94 public ClusterBase getClusterByResourceKey(int resourceKey) {
95 throw new UnsupportedOperationException();
96 // return impl.getClusterByResourceKey(resourceKey);
100 public long getClusterIdOrCreate(ClusterUID clusterUID) {
101 return impl.getClusterIdOrCreate(clusterUID);
105 public void addStatement(Object cluster) {
110 public void cancelStatement(Object cluster) {
115 public void removeStatement(Object cluster) {
120 public void removeValue(Object cluster) {
125 public void setImmutable(Object cluster, boolean immutable) {
130 public void setDeleted(Object cluster, boolean deleted) {
131 // TODO Auto-generated method stub
138 public void cancelValue(Object cluster) {
139 throw new UnsupportedOperationException();
143 public void setValue(Object cluster, long clusterId, byte[] bytes,
149 public void modiValue(Object _cluster, long clusterId, long voffset,
150 int length, byte[] bytes, int offset) {
155 public void createResource(Object cluster, short resourceIndex,
161 public void addStatementIndex(Object cluster, int resourceKey,
162 ClusterUID clusterUID, byte op) {
167 public void setStreamOff(boolean setOff) {
168 throw new UnsupportedOperationException();
172 public boolean getStreamOff() {
177 private static class ResourceSegment {
178 public long valueSize;
182 ResourceSegment(long valueSize, byte[] bytes) {
183 this.valueSize = valueSize;
188 public ResourceSegment getResourceSegment(int resourceIndex, ClusterUID clusterUID, long offset, short size)
189 throws DatabaseException {
191 System.out.println("DEBUG: getResourceSegment ri=" + resourceIndex + " cid=" + clusterUID + " offset=" + offset + " size=" + size);
193 org.simantics.db.Database.Session.ResourceSegment t = impl.getResourceSegment(clusterUID.asBytes(), resourceIndex, offset, size);
194 return new ResourceSegment(t.getValueSize(), t.getSegment());
198 protected byte[] getValueBig(ClusterBase cluster, int resourceIndex, int offset, int length) throws DatabaseException {
203 ClusterUID clusterUID = cluster.clusterUID;
205 return impl.getResourceFile(clusterUID.asBytes(), resourceIndex);
209 protected InputStream getValueStreamBig(ClusterBase cluster, final int resourceIndex, int offset, int length) throws DatabaseException {
211 final ClusterUID clusterUID = cluster.clusterUID;
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);
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);
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;
230 long rSize = s.valueSize - offset;
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);
238 final int finalLength = length;
240 return new InputStream() {
242 int left = finalLength;
243 long valueOffset = 0;
245 ResourceSegment _s = s;
248 public int read() throws IOException {
250 if(left <= 0) throw new IllegalStateException();
252 if(offset == _s.bytes.length) {
253 short slen = (short)Math.min(left, IMAX);
254 valueOffset += _s.bytes.length;
256 _s = getResourceSegment(resourceIndex, clusterUID, valueOffset, slen);
257 } catch (DatabaseException e) {
258 throw new IOException(e);
264 int result = _s.bytes[offset++];
265 if(result < 0) result += 256;
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);
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);
289 public byte[] getValueEx(int resourceIndex, long clusterId, long voffset,
290 int length) throws DatabaseException {
291 throw new UnsupportedOperationException();
295 public long getValueSizeEx(int resourceIndex, long clusterId)
296 throws DatabaseException {
297 throw new UnsupportedOperationException();
301 public int wait4RequestsLess(int limit) throws DatabaseException {
302 throw new UnsupportedOperationException();
306 public Session getSession() {
311 public IClusterTable getClusterTable() {
316 public <T extends ClusterI> T getClusterByClusterUIDOrMakeProxy(ClusterUID clusterUID) {
318 return (T)impl.getClusterByClusterUIDOrMakeProxy(clusterUID);
319 } catch (DatabaseException e) {
326 public <T extends ClusterI> T getClusterProxyByResourceKey(int resourceKey) {
328 return impl.getClusterProxyByResourceKey(resourceKey);
329 } catch (DatabaseException e) {
336 public int getClusterKeyByUID(long id1, long id2) throws DatabaseException {
337 return impl.getClusterKeyByUID(id1, id2);