Cluster loading problem fix made by Antti 16/1116/2
authorjsimomaa <jani.simomaa@gmail.com>
Mon, 16 Oct 2017 20:31:41 +0000 (23:31 +0300)
committerTuukka Lehtonen <tuukka.lehtonen@semantum.fi>
Mon, 16 Oct 2017 21:00:50 +0000 (00:00 +0300)
It was possible that at first a proxy cluster was created and that was
used after the initial cluster was created. Therefore ensure that
proxied clusters are actually loaded. More technical details from Antti

refs #7554

Change-Id: I2867eddb69addba7f24b7c5d1bd4825c94f7aa75

bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterChangeManager.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/ClusterTable.java
bundles/org.simantics.db.procore/src/fi/vtt/simantics/procore/internal/SessionImplSocket.java

index 83088135559fe16603c060a13325436b6e3fbd34..048a775196d46145fd3e00b9b5605d013f1dcab3 100644 (file)
@@ -41,7 +41,7 @@ public class ClusterChangeManager {
         if(clusterChanges.add(change)) {
             removeList.add(change);
         } else {
         if(clusterChanges.add(change)) {
             removeList.add(change);
         } else {
-            new Exception("trying to add change that already exists").printStackTrace();
+            new Exception("trying to add change that already exists " + change.clusterUID + " " + System.identityHashCode(change.clusterImpl)).printStackTrace();
         }
         updateChangeCounters();
     }
         }
         updateChangeCounters();
     }
index 40b2530f2a569a4dedfdb7295095895871074f1d..123f346a4dd0322254aa74bfd1a259b9bd07357c 100644 (file)
@@ -22,9 +22,9 @@ import java.util.concurrent.Semaphore;
 import org.simantics.databoard.Bindings;
 import org.simantics.db.ClusterCreator;
 import org.simantics.db.Database;
 import org.simantics.databoard.Bindings;
 import org.simantics.db.ClusterCreator;
 import org.simantics.db.Database;
+import org.simantics.db.Database.Session.ClusterChanges;
 import org.simantics.db.DevelopmentKeys;
 import org.simantics.db.SessionVariables;
 import org.simantics.db.DevelopmentKeys;
 import org.simantics.db.SessionVariables;
-import org.simantics.db.Database.Session.ClusterChanges;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.ClusterDoesNotExistException;
 import org.simantics.db.exception.DatabaseException;
 import org.simantics.db.common.utils.Logger;
 import org.simantics.db.exception.ClusterDoesNotExistException;
 import org.simantics.db.exception.DatabaseException;
@@ -529,17 +529,19 @@ public final class ClusterTable implements IClusterTable {
 
     ClusterImpl getNewResourceCluster(ClusterSupport cs, GraphSession graphSession, boolean writeOnly)
     throws DatabaseException {
 
     ClusterImpl getNewResourceCluster(ClusterSupport cs, GraphSession graphSession, boolean writeOnly)
     throws DatabaseException {
+        ClusterImpl result = null;
         if (Constants.NewClusterId == newResourceClusterId) {
             newResourceClusterId = graphSession.newClusterId();
         if (Constants.NewClusterId == newResourceClusterId) {
             newResourceClusterId = graphSession.newClusterId();
-            return getClusterByClusterIdOrMake(newResourceClusterId, writeOnly);
+            result = getClusterByClusterIdOrMake(newResourceClusterId, writeOnly);
         } else {
             ClusterImpl cluster = getClusterByClusterIdOrThrow(newResourceClusterId);
             if (cluster.getNumberOfResources(cs) >= CLUSTER_FILL_SIZE) {
                 newResourceClusterId = graphSession.newClusterId();
                 cluster = getClusterByClusterIdOrMake(newResourceClusterId, writeOnly);
             }
         } else {
             ClusterImpl cluster = getClusterByClusterIdOrThrow(newResourceClusterId);
             if (cluster.getNumberOfResources(cs) >= CLUSTER_FILL_SIZE) {
                 newResourceClusterId = graphSession.newClusterId();
                 cluster = getClusterByClusterIdOrMake(newResourceClusterId, writeOnly);
             }
-            return cluster;
+            result = cluster;
         }
         }
+        return ensureLoaded(result);
     }
 
     void flushCluster(GraphSession graphSession) {
     }
 
     void flushCluster(GraphSession graphSession) {
@@ -818,25 +820,9 @@ public final class ClusterTable implements IClusterTable {
     TLongIntHashMap clusterLoadHistogram = new TLongIntHashMap();
     int clusterLoadCounter = 0;
 
     TLongIntHashMap clusterLoadHistogram = new TLongIntHashMap();
     int clusterLoadCounter = 0;
 
-    @SuppressWarnings("unchecked")
-    public final <T extends ClusterI> T getClusterByResourceKey(final int resourceKey) {
-        int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);
-        if (ClusterTraitsBase.isVirtualClusterKey(clusterKey))
-            throw new RuntimeException("Tried to get a persistent cluster for a virtual resource.");
-        ClusterI c = clusterArray[clusterKey];
-        if (c == null)
-            return null;
-        if (c.isLoaded()) {
-            if ((counter++ & 4095) == 0)
-                refreshImportance((ClusterImpl) c);
-            return (T) c;
-        }
-        if (!(c instanceof ClusterSmall)) {
-            Logger.defaultLogError("Proxy must be instance of ClusterSmall");
-            return null;
-        }
+    private <T extends ClusterI> T ensureLoaded(T c) {
         ClusterI cluster;
         ClusterI cluster;
-        ClusterSmall cs = (ClusterSmall) c;
+        ClusterImpl cs = (ClusterImpl) c;
         try {
             if(DebugPolicy.REPORT_CLUSTER_LOADING) {
                 long start = System.nanoTime();
         try {
             if(DebugPolicy.REPORT_CLUSTER_LOADING) {
                 long start = System.nanoTime();
@@ -861,13 +847,32 @@ public final class ClusterTable implements IClusterTable {
             Logger.defaultLogError(e);
             if (DebugPolicy.REPORT_CLUSTER_EVENTS)
                 e.printStackTrace();
             Logger.defaultLogError(e);
             if (DebugPolicy.REPORT_CLUSTER_EVENTS)
                 e.printStackTrace();
-            String msg = "Failed to load cluster " + cs.getClusterUID() + " for resource key " + resourceKey
-                    + " resourceId=" + (((cs.getClusterId() << 16 + (resourceKey & 65535))));
+            String msg = "Failed to load cluster " + cs.getClusterUID();// + " resourceId=" + (((cs.getClusterId() << 16 + (resourceKey & 65535))));
             // TODO: this jams the system => needs refactoring.
             throw new RuntimeDatabaseException(msg, e);
         }
         return (T) cluster;
     }
             // TODO: this jams the system => needs refactoring.
             throw new RuntimeDatabaseException(msg, e);
         }
         return (T) cluster;
     }
+    
+    @SuppressWarnings("unchecked")
+    public final <T extends ClusterI> T getClusterByResourceKey(final int resourceKey) {
+        int clusterKey = ClusterTraitsBase.getClusterKeyFromResourceKeyNoThrow(resourceKey);
+        if (ClusterTraitsBase.isVirtualClusterKey(clusterKey))
+            throw new RuntimeException("Tried to get a persistent cluster for a virtual resource.");
+        ClusterI c = clusterArray[clusterKey];
+        if (c == null)
+            return null;
+        if (c.isLoaded()) {
+            if ((counter++ & 4095) == 0)
+                refreshImportance((ClusterImpl) c);
+            return (T) c;
+        }
+        if (!(c instanceof ClusterSmall)) {
+            Logger.defaultLogError("Proxy must be instance of ClusterSmall");
+            return null;
+        }
+        return ensureLoaded((T)c);
+    }
 
     @SuppressWarnings("unchecked")
     final <T extends ClusterI> T checkedGetClusterByResourceKey(final int resourceKey) {
 
     @SuppressWarnings("unchecked")
     final <T extends ClusterI> T checkedGetClusterByResourceKey(final int resourceKey) {
index c286f02c7d4434e69fe31fc0978ef057e16764d8..2ff47c29266912afa68ee0515fd5c47d1b809b89 100644 (file)
@@ -849,14 +849,17 @@ public abstract class SessionImplSocket implements Session, WriteRequestSchedule
         private void maintainCluster(ClusterImpl before, ClusterI after_) {
             if(after_ != null && after_ != before) {
                 ClusterImpl after = (ClusterImpl)after_;
         private void maintainCluster(ClusterImpl before, ClusterI after_) {
             if(after_ != null && after_ != before) {
                 ClusterImpl after = (ClusterImpl)after_;
-                if(currentCluster == before) currentCluster = after;
+                if(currentCluster == before) {
+                    currentCluster = after;
+                }
                 clusterTable.replaceCluster(after);
             }
         }
 
         public int createResourceKey(int foreignCounter) throws DatabaseException {
                 clusterTable.replaceCluster(after);
             }
         }
 
         public int createResourceKey(int foreignCounter) throws DatabaseException {
-            if(currentCluster == null)
+            if(currentCluster == null) {
                 currentCluster = getNewResourceCluster();
                 currentCluster = getNewResourceCluster();
+            }
             if(currentCluster.getNumberOfResources(clusterTranslator) == ClusterTable.CLUSTER_FILL_SIZE) {
                 ClusterWriteOnly newCluster = (ClusterWriteOnly)getNewResourceCluster();
                 newCluster.foreignLookup = new byte[foreignCounter];
             if(currentCluster.getNumberOfResources(clusterTranslator) == ClusterTable.CLUSTER_FILL_SIZE) {
                 ClusterWriteOnly newCluster = (ClusterWriteOnly)getNewResourceCluster();
                 newCluster.foreignLookup = new byte[foreignCounter];