]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.layer0/src/org/simantics/db/layer0/util/SessionGarbageCollection.java
Fixed bug in cluster collection logic that caused it to not operate
[simantics/platform.git] / bundles / org.simantics.db.layer0 / src / org / simantics / db / layer0 / util / SessionGarbageCollection.java
index acbf18485f635d3d0ad136cc78b71a6922ca861d..c48ec36309e601cf885f9b8125f16f7e79c579f8 100644 (file)
-/*******************************************************************************\r
- * Copyright (c) 2007, 2011 Association for Decentralized Information Management\r
- * in Industry THTH ry.\r
- * All rights reserved. This program and the accompanying materials\r
- * are made available under the terms of the Eclipse Public License v1.0\r
- * which accompanies this distribution, and is available at\r
- * http://www.eclipse.org/legal/epl-v10.html\r
- *\r
- * Contributors:\r
- *     VTT Technical Research Centre of Finland - initial API and implementation\r
- *******************************************************************************/\r
-package org.simantics.db.layer0.util;\r
-\r
-import java.util.function.Consumer;\r
-\r
-import org.eclipse.core.runtime.IProgressMonitor;\r
-import org.eclipse.core.runtime.NullProgressMonitor;\r
-import org.simantics.db.ReadGraph;\r
-import org.simantics.db.Session;\r
-import org.simantics.db.WriteGraph;\r
-import org.simantics.db.common.request.WriteRequest;\r
-import org.simantics.db.common.utils.Logger;\r
-import org.simantics.db.exception.DatabaseException;\r
-import org.simantics.db.service.ClusterControl;\r
-import org.simantics.db.service.LifecycleSupport;\r
-import org.simantics.db.service.QueryControl;\r
-import org.simantics.utils.DataContainer;\r
-import org.simantics.utils.datastructures.Callback;\r
-\r
-/**\r
- * @author Tuukka Lehtonen\r
- */\r
-public class SessionGarbageCollection {\r
-    /**\r
-     * collect everything possible, default target is 0 queries.\r
-     */\r
-    private static int DEFAULT_ALLOWED_TIME = 300;\r
-    public static int getDefaultQueryTarget() {\r
-        return DEFAULT_ALLOWED_TIME;\r
-    }\r
-    public static void setDefaultAllowedTime(int a) {\r
-        DEFAULT_ALLOWED_TIME = a;\r
-    }\r
-    /**\r
-     * Default maximum cluster memory consumption target is 32MB.\r
-     */\r
-    private static int DEFAULT_CLUSTER_TARGET = -1;\r
-    public static int getDefaultClusterTarget() {\r
-        return DEFAULT_CLUSTER_TARGET;\r
-    }\r
-    public static void setDefaultClusterTarget(int a) {\r
-        DEFAULT_CLUSTER_TARGET = a;\r
-    }\r
-    /**\r
-     * @param monitor <code>null</code> if progress monitor not available\r
-     * @param session the session to GC\r
-     * @param sync <code>true</code> to block until gc is completed\r
-     * @param errorCallback callback for any errors occuring during the\r
-     *        operation or <code>null</code> to ignore errors\r
-     */\r
-    public static boolean gc(IProgressMonitor monitor, Session session, boolean sync,\r
-            final Consumer<DatabaseException> errorCallback) {\r
-       long took = gc(monitor, session, sync, errorCallback, DEFAULT_ALLOWED_TIME, DEFAULT_CLUSTER_TARGET);\r
-        return ((16*took) / DEFAULT_ALLOWED_TIME) > 15;\r
-    }\r
-    \r
-    public static void gc(ReadGraph graph, final int allowedTimeInMs, final int clusterTarget) throws DatabaseException {\r
-       doIt(null, graph, allowedTimeInMs, clusterTarget);\r
-    }\r
-\r
-    private static void doIt(IProgressMonitor _monitor, ReadGraph graph, final int allowedTimeInMs, final int clusterTarget) {\r
-       if(_monitor == null) _monitor = new NullProgressMonitor();\r
-        QueryControl qc = graph.getService(QueryControl.class);\r
-        ClusterControl cc = graph.getService(ClusterControl.class);\r
-        _monitor.beginTask("Collect clusters", IProgressMonitor.UNKNOWN);\r
-        cc.gc(graph, clusterTarget);\r
-        _monitor.beginTask("Collect queries", IProgressMonitor.UNKNOWN);\r
-        qc.gc(graph, allowedTimeInMs);\r
-    }\r
-    \r
-    /**\r
-     * @param monitor\r
-     * @param session\r
-     * @param sync\r
-     * @param errorCallback\r
-     */\r
-    /**\r
-     * @param monitor <code>null</code> if progress monitor not available\r
-     * @param session the session to GC\r
-     * @param sync <code>true</code> to block until gc is completed\r
-     * @param errorCallback callback for any errors occuring during the\r
-     *        operation or <code>null</code> to ignore errors\r
-     * @param allowedTimeInMs the time allowed for query collection in ms\r
-     * @param clusterTarget target for the maximum amount of memory in bytes to\r
-     *        be consumed by cluster caches after collection.\r
-     */\r
-    public static long gc(IProgressMonitor monitor, Session session, boolean sync,\r
-            final Consumer<DatabaseException> errorCallback, final int allowedTimeInMs, final int clusterTarget) {\r
-        if (monitor == null)\r
-            monitor = new NullProgressMonitor();\r
-        final IProgressMonitor _monitor = monitor;\r
-        if (session == null)\r
-            throw new NullPointerException("null session");\r
-\r
-        final DataContainer<Long> took = new DataContainer<Long>(0L);\r
-        \r
-        WriteRequest request = new WriteRequest() {\r
-            @Override\r
-            public void perform(WriteGraph graph) throws DatabaseException {\r
-               long start = System.nanoTime();\r
-               doIt(_monitor, graph, allowedTimeInMs, clusterTarget);\r
-               long duration = System.nanoTime()-start;\r
-               took.set((long)(duration*1e-6));\r
-            }\r
-        };\r
-        \r
-        LifecycleSupport lfs = session.peekService(LifecycleSupport.class);\r
-        if (lfs == null || lfs.isClosed() || lfs.isClosing())\r
-            return 0L;\r
-        \r
-        if (sync) {\r
-            try {\r
-                session.syncRequest(request);\r
-            } catch (DatabaseException e) {\r
-                if (errorCallback != null)\r
-                    errorCallback.accept(e);\r
-                else\r
-                    Logger.defaultLogError(e);\r
-            }\r
-        } else {\r
-            session.asyncRequest(request, new Callback<DatabaseException>() {\r
-                @Override\r
-                public void run(DatabaseException e) {\r
-                    if (e != null) {\r
-                        if (errorCallback != null)\r
-                            errorCallback.accept(e);\r
-                        else\r
-                            Logger.defaultLogError(e);\r
-                    }\r
-                }\r
-            });\r
-        }\r
-        \r
-        return took.get();\r
-        \r
-    }\r
-\r
-}\r
+/*******************************************************************************
+ * Copyright (c) 2007, 2011 Association for Decentralized Information Management
+ * in Industry THTH ry.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     VTT Technical Research Centre of Finland - initial API and implementation
+ *******************************************************************************/
+package org.simantics.db.layer0.util;
+
+import java.util.function.Consumer;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.simantics.db.ReadGraph;
+import org.simantics.db.Session;
+import org.simantics.db.WriteGraph;
+import org.simantics.db.common.request.WriteRequest;
+import org.simantics.db.common.utils.Logger;
+import org.simantics.db.exception.DatabaseException;
+import org.simantics.db.service.ClusterControl;
+import org.simantics.db.service.LifecycleSupport;
+import org.simantics.db.service.QueryControl;
+import org.simantics.utils.DataContainer;
+
+/**
+ * @author Tuukka Lehtonen
+ */
+public class SessionGarbageCollection {
+    /**
+     * collect everything possible, default target is 0 queries.
+     */
+    private static int DEFAULT_ALLOWED_TIME = 300;
+    public static int getDefaultQueryTarget() {
+        return DEFAULT_ALLOWED_TIME;
+    }
+    public static void setDefaultAllowedTime(int a) {
+        DEFAULT_ALLOWED_TIME = a;
+    }
+    /**
+     * Default maximum cluster memory consumption target is 32MB.
+     */
+    private static int DEFAULT_CLUSTER_TARGET = -1;
+    public static int getDefaultClusterTarget() {
+        return DEFAULT_CLUSTER_TARGET;
+    }
+    public static void setDefaultClusterTarget(int a) {
+        DEFAULT_CLUSTER_TARGET = a;
+    }
+    /**
+     * @param monitor <code>null</code> if progress monitor not available
+     * @param session the session to GC
+     * @param sync <code>true</code> to block until gc is completed
+     * @param errorCallback callback for any errors occuring during the
+     *        operation or <code>null</code> to ignore errors
+     */
+    public static boolean gc(IProgressMonitor monitor, Session session, boolean sync,
+            final Consumer<DatabaseException> errorCallback) {
+       long took = gc(monitor, session, sync, errorCallback, DEFAULT_ALLOWED_TIME, DEFAULT_CLUSTER_TARGET);
+        return ((16*took) / DEFAULT_ALLOWED_TIME) > 15;
+    }
+
+    public static void gc(ReadGraph graph, final int allowedTimeInMs, final int clusterTarget) throws DatabaseException {
+        doIt(null, graph, allowedTimeInMs, clusterTarget);
+    }
+
+    public static void gc(IProgressMonitor monitor, ReadGraph graph, final int allowedTimeInMs, final int clusterTarget) throws DatabaseException {
+        doIt(monitor, graph, allowedTimeInMs, clusterTarget);
+    }
+
+    private static void doIt(IProgressMonitor _monitor, ReadGraph graph, final int allowedTimeInMs, final int clusterTarget) {
+        if(_monitor == null) _monitor = new NullProgressMonitor();
+        QueryControl qc = graph.getService(QueryControl.class);
+        ClusterControl cc = graph.getService(ClusterControl.class);
+        _monitor.beginTask("Collect clusters", IProgressMonitor.UNKNOWN);
+        //cc.gc(graph, clusterTarget);
+        if(clusterTarget == -1) {
+            int used = cc.used();
+            //System.err.println("session gc, cluster use = " + used);
+            int baseline = 32*(1<<20);
+            if(used > baseline) {
+                int dynamicTarget = (int)(0.95 * (used-baseline)) + baseline;
+                cc.gc(graph, dynamicTarget);
+            }
+        } else {
+            cc.gc(graph, clusterTarget);
+        }
+        _monitor.beginTask("Collect queries", IProgressMonitor.UNKNOWN);
+        qc.gc(graph, allowedTimeInMs);
+    }
+
+    /**
+     * @param monitor
+     * @param session
+     * @param sync
+     * @param errorCallback
+     */
+    /**
+     * @param monitor <code>null</code> if progress monitor not available
+     * @param session the session to GC
+     * @param sync <code>true</code> to block until gc is completed
+     * @param errorCallback callback for any errors occuring during the
+     *        operation or <code>null</code> to ignore errors
+     * @param allowedTimeInMs the time allowed for query collection in ms
+     * @param clusterTarget target for the maximum amount of memory in bytes to
+     *        be consumed by cluster caches after collection.
+     */
+    public static long gc(IProgressMonitor monitor, Session session, boolean sync,
+            final Consumer<DatabaseException> errorCallback, final int allowedTimeInMs, final int clusterTarget) {
+        if (monitor == null)
+            monitor = new NullProgressMonitor();
+        final IProgressMonitor _monitor = monitor;
+        if (session == null)
+            throw new NullPointerException("null session");
+
+        final DataContainer<Long> took = new DataContainer<Long>(0L);
+        
+        WriteRequest request = new WriteRequest() {
+            @Override
+            public void perform(WriteGraph graph) throws DatabaseException {
+               long start = System.nanoTime();
+               doIt(_monitor, graph, allowedTimeInMs, clusterTarget);
+               long duration = System.nanoTime()-start;
+               took.set((long)(duration*1e-6));
+            }
+        };
+        
+        LifecycleSupport lfs = session.peekService(LifecycleSupport.class);
+        if (lfs == null || lfs.isClosed() || lfs.isClosing())
+            return 0L;
+        
+        if (sync) {
+            try {
+                session.syncRequest(request);
+            } catch (DatabaseException e) {
+                if (errorCallback != null)
+                    errorCallback.accept(e);
+                else
+                    Logger.defaultLogError(e);
+            }
+        } else {
+            session.asyncRequest(request, e -> {
+                if (e != null) {
+                    if (errorCallback != null)
+                        errorCallback.accept(e);
+                    else
+                        Logger.defaultLogError(e);
+                }
+            });
+        }
+        
+        return took.get();
+        
+    }
+
+}