]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterSupport2.java
Sharing org.simantics.acorn for everyone to use
[simantics/platform.git] / bundles / org.simantics.acorn / src / org / simantics / acorn / internal / ClusterSupport2.java
diff --git a/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterSupport2.java b/bundles/org.simantics.acorn/src/org/simantics/acorn/internal/ClusterSupport2.java
new file mode 100644 (file)
index 0000000..7cd007a
--- /dev/null
@@ -0,0 +1,340 @@
+package org.simantics.acorn.internal;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
+
+import org.simantics.acorn.ClusterManager;
+import org.simantics.db.Session;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.impl.ClusterBase;
+import org.simantics.db.impl.ClusterI;
+import org.simantics.db.impl.ClusterSupport;
+import org.simantics.db.impl.IClusterTable;
+import org.simantics.db.service.ClusterUID;
+
+import gnu.trove.map.hash.TIntObjectHashMap;
+
+public class ClusterSupport2 implements ClusterSupport, IClusterTable {
+       
+       final private static boolean DEBUG = false;
+
+       public ClusterManager impl;
+       
+       public TIntObjectHashMap<ClusterUID> uidCache = new TIntObjectHashMap<ClusterUID>(); 
+       
+       public ClusterSupport2(ClusterManager impl) {
+               this.impl = impl;
+       }
+       
+       @Override
+       public int createClusterKeyByClusterUID(ClusterUID clusterUID, long clusterId) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public ClusterBase getClusterByClusterUIDOrMake(ClusterUID clusterUID) {
+               try {
+            return impl.getClusterByClusterUIDOrMake(clusterUID);
+        } catch (DatabaseException e) {
+            e.printStackTrace();
+            return null;
+        }
+       }
+
+       @Override
+       public ClusterBase getClusterByClusterId(long clusterId) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public ClusterBase getClusterByClusterKey(int clusterKey) {
+               throw new UnsupportedOperationException();
+       }
+
+       ReentrantReadWriteLock uidLock = new ReentrantReadWriteLock();
+       ReadLock uidRead = uidLock.readLock();
+       WriteLock uidWrite = uidLock.writeLock();
+       
+       @Override
+       public ClusterUID getClusterUIDByResourceKey(int resourceKey) throws DatabaseException {
+
+               ClusterUID cuid;
+               
+               uidRead.lock();
+               cuid = uidCache.get(resourceKey >> 12);
+               uidRead.unlock();
+               if(cuid != null) return cuid;
+               uidWrite.lock();
+               cuid = uidCache.get(resourceKey >> 12);
+               if(cuid == null) {
+                       cuid = impl.getClusterUIDByResourceKeyWithoutMutex(resourceKey); 
+                       uidCache.put(resourceKey >> 12, cuid);
+               }
+               uidWrite.unlock();
+               
+               return cuid;
+               
+       }
+       
+       @Override
+       public int getClusterKeyByClusterUIDOrMake(ClusterUID clusterUID) {
+               return impl.getClusterKeyByClusterUIDOrMakeWithoutMutex(clusterUID);
+       }
+       
+    @Override
+    public int getClusterKeyByClusterUIDOrMake(long id1, long id2) {
+               throw new UnsupportedOperationException();
+    }
+
+       @Override
+       public ClusterBase getClusterByResourceKey(int resourceKey) {
+               throw new UnsupportedOperationException();
+//             return impl.getClusterByResourceKey(resourceKey);
+       }
+
+       @Override
+       public long getClusterIdOrCreate(ClusterUID clusterUID) {
+               return impl.getClusterIdOrCreate(clusterUID);
+       }
+
+       @Override
+       public void addStatement(Object cluster) {
+               // nop
+       }
+
+       @Override
+       public void cancelStatement(Object cluster) {
+               // nop
+       }
+
+       @Override
+       public void removeStatement(Object cluster) {
+               // nop
+       }
+
+       @Override
+       public void removeValue(Object cluster) {
+               // nop
+       }
+
+       @Override
+       public void setImmutable(Object cluster, boolean immutable) {
+               // nop
+       }
+
+       @Override
+       public void setDeleted(Object cluster, boolean deleted) {
+               // TODO Auto-generated method stub
+               
+       }
+
+       
+       
+       @Override
+       public void cancelValue(Object cluster) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public void setValue(Object cluster, long clusterId, byte[] bytes,
+                       int length) {
+               // nop
+       }
+
+       @Override
+       public void modiValue(Object _cluster, long clusterId, long voffset,
+                       int length, byte[] bytes, int offset) {
+               // nop
+       }
+
+       @Override
+       public void createResource(Object cluster, short resourceIndex,
+                       long clusterId) {
+               // No op
+       }
+
+       @Override
+       public void addStatementIndex(Object cluster, int resourceKey,
+                       ClusterUID clusterUID, byte op) {
+               // No op
+       }
+
+       @Override
+       public void setStreamOff(boolean setOff) {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public boolean getStreamOff() {
+               return true;
+       }
+
+       
+    private static class ResourceSegment {
+        public long   valueSize;
+
+        public byte[] bytes;
+
+        ResourceSegment(long valueSize, byte[] bytes) {
+            this.valueSize = valueSize;
+            this.bytes = bytes;
+        }
+    }
+
+    public ResourceSegment getResourceSegment(int resourceIndex, ClusterUID clusterUID, long offset, short size)
+    throws DatabaseException {
+        if (DEBUG)
+            System.out.println("DEBUG: getResourceSegment ri=" + resourceIndex + " cid=" + clusterUID + " offset=" + offset + " size=" + size);
+        
+        org.simantics.db.Database.Session.ResourceSegment t = impl.getResourceSegment(clusterUID.asBytes(), resourceIndex, offset, size);
+        return new ResourceSegment(t.getValueSize(), t.getSegment());
+        
+    }
+    
+    protected byte[] getValueBig(ClusterBase cluster, int resourceIndex, int offset, int length) throws DatabaseException {
+    
+       assert(offset == 0);
+       assert(length == 0);
+       
+       ClusterUID clusterUID = cluster.clusterUID;
+       
+       return impl.getResourceFile(clusterUID.asBytes(), resourceIndex);
+       
+    }
+
+    protected InputStream getValueStreamBig(ClusterBase cluster, final int resourceIndex, int offset, int length) throws DatabaseException {
+
+       final ClusterUID clusterUID = cluster.clusterUID;
+       
+       if (DEBUG)
+               System.out.println("DEBUG: getResourceFile ri=" + resourceIndex + " cid=" + clusterUID + " off=" + offset + " len=" + length);
+       final int IMAX = 0xFFFF;
+       short slen = (short)Math.min(length != 0 ? length : IMAX, IMAX);
+       final ResourceSegment s = getResourceSegment(resourceIndex, clusterUID, offset, slen);
+       if (s.valueSize < 0)
+               throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
+                               " cluster=" + clusterUID + " off=" + offset + " len=" + length + " (1).");
+       int ilen = (int)slen & 0xFFFF;
+       assert(s.bytes.length <= ilen);
+       if (0 == length) {
+               if (s.valueSize > Integer.MAX_VALUE)
+                       throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
+                                       " cluster=" + clusterUID + " off=" + offset + " len=" + length +
+                                       ". Value size=" + s.valueSize + " (2).");
+               length = (int)s.valueSize;
+       }
+       long rSize = s.valueSize - offset;
+       if (rSize < length)
+               throw new DatabaseException("Failed to get value for resource index=" + resourceIndex +
+                               " cluster=" + clusterUID + " off=" + offset + " len=" + length +
+                               ". Value size=" + s.valueSize + " (3).");
+       else if (length <= IMAX)
+               return new ByteArrayInputStream(s.bytes);
+
+       final int finalLength = length;
+
+       return new InputStream() {
+
+               int left = finalLength;
+               long valueOffset = 0;
+               int offset = 0;
+               ResourceSegment _s = s;
+
+               @Override
+               public int read() throws IOException {
+
+                       if(left <= 0) throw new IllegalStateException();
+
+                       if(offset == _s.bytes.length) {
+                               short slen = (short)Math.min(left, IMAX);
+                               valueOffset += _s.bytes.length;
+                               try {
+                                       _s = getResourceSegment(resourceIndex, clusterUID, valueOffset, slen);
+                               } catch (DatabaseException e) {
+                                       throw new IOException(e);
+                               }
+                               offset = 0;
+                       }
+
+                       left--;
+                       int result = _s.bytes[offset++];
+                       if(result < 0) result += 256;
+                       return result;
+
+               }
+
+       };
+
+    }
+       
+       @Override
+       public InputStream getValueStreamEx(int resourceIndex, long clusterId)
+                       throws DatabaseException {
+               ClusterBase cluster = impl.getClusterByClusterUIDOrMakeProxy(ClusterUID.make(0, clusterId));
+               return getValueStreamBig(cluster, resourceIndex, 0, 0);
+       }
+
+       @Override
+       public byte[] getValueEx(int resourceIndex, long clusterId)
+                       throws DatabaseException {
+               ClusterBase cluster = impl.getClusterByClusterUIDOrMakeProxy(ClusterUID.make(0, clusterId));
+               return getValueBig(cluster, resourceIndex, 0, 0);
+       }
+
+       @Override
+       public byte[] getValueEx(int resourceIndex, long clusterId, long voffset,
+                       int length) throws DatabaseException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public long getValueSizeEx(int resourceIndex, long clusterId)
+                       throws DatabaseException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public int wait4RequestsLess(int limit) throws DatabaseException {
+               throw new UnsupportedOperationException();
+       }
+
+       @Override
+       public Session getSession() {
+               return null;
+       }
+
+       @Override
+       public IClusterTable getClusterTable() {
+               return this;
+       }
+
+       @Override
+       public <T extends ClusterI> T getClusterByClusterUIDOrMakeProxy(ClusterUID clusterUID) {
+               try {
+            return (T)impl.getClusterByClusterUIDOrMakeProxy(clusterUID);
+        } catch (DatabaseException e) {
+            e.printStackTrace();
+            return null;
+        }
+       }
+
+       @Override
+       public <T extends ClusterI> T getClusterProxyByResourceKey(int resourceKey) {
+               try {
+            return impl.getClusterProxyByResourceKey(resourceKey);
+        } catch (DatabaseException e) {
+            e.printStackTrace();
+            return null;
+        }
+       }
+
+       @Override
+       public int getClusterKeyByUID(long id1, long id2) throws DatabaseException {
+               return impl.getClusterKeyByUID(id1, id2);
+       }
+
+}