]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db.common/src/org/simantics/db/common/Indexing.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db.common / src / org / simantics / db / common / Indexing.java
diff --git a/bundles/org.simantics.db.common/src/org/simantics/db/common/Indexing.java b/bundles/org.simantics.db.common/src/org/simantics/db/common/Indexing.java
new file mode 100644 (file)
index 0000000..f910663
--- /dev/null
@@ -0,0 +1,154 @@
+/*******************************************************************************\r
+ * Copyright (c) 2012 Association for Decentralized Information Management in\r
+ * 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.common;\r
+\r
+import java.util.HashMap;\r
+import java.util.HashSet;\r
+import java.util.Map;\r
+import java.util.Set;\r
+import java.util.UUID;\r
+import java.util.concurrent.atomic.AtomicBoolean;\r
+\r
+import org.simantics.db.Resource;\r
+import org.simantics.db.WriteOnlyGraph;\r
+import org.simantics.db.common.utils.Logger;\r
+\r
+/**\r
+ * A internal temporary store for database indexing-related low-level utilities\r
+ * and static data.\r
+ * \r
+ * This will be moved to more a more logical location at some point.\r
+ * \r
+ * @author Antti Villberg\r
+ * @author Tuukka Lehtonen\r
+ * @since 1.8\r
+ */\r
+public class Indexing {\r
+\r
+    private static final boolean PROFILE                      = false;\r
+\r
+    private static Set<UUID>     indexPendings                = new HashSet<UUID>();\r
+\r
+    private static AtomicBoolean dependenciesIndexingDisabled = new AtomicBoolean();\r
+\r
+    private static int indexPendingCounter = 0;\r
+\r
+    private static Map<Resource, Map<Class<?>, Object>> caches = new HashMap<Resource, Map<Class<?>, Object>>(); \r
+    \r
+    private static boolean useIndexing = true;\r
+    \r
+    @SuppressWarnings("unchecked")\r
+       public static <T> T getCache(Resource root, Class<T> clazz) {\r
+       Map<Class<?>,Object> cache = caches.get(root);\r
+       if(cache == null) return null;\r
+       return (T)cache.get(clazz);\r
+    }\r
+    \r
+    public static <T> T createCache(Resource root, T object) {\r
+       Map<Class<?>,Object> cache = caches.get(root);\r
+       if(cache == null) {\r
+               cache = new HashMap<Class<?>,Object>();\r
+               caches.put(root, cache);\r
+       }\r
+       cache.put(object.getClass(), object);\r
+       return object;\r
+    }\r
+    \r
+    public static void clearCaches(Resource root) {\r
+       caches.remove(root);\r
+    }\r
+    \r
+    public static UUID makeIndexPending() {\r
+        synchronized (indexPendings) {\r
+            UUID guid = UUID.randomUUID();\r
+            indexPendings.add(guid);\r
+            return guid;\r
+        }\r
+    }\r
+\r
+    public static void releaseIndexPending(UUID guid) {\r
+        synchronized (indexPendings) {\r
+            indexPendings.remove(guid);\r
+            if (indexPendings.isEmpty()) {\r
+                indexPendings.notifyAll();\r
+                indexPendingCounter++;\r
+            }\r
+        }\r
+    }\r
+\r
+    public static int getIndexPendingCounter() {\r
+        synchronized (indexPendings) {\r
+            return indexPendingCounter;\r
+        }\r
+    }\r
+    \r
+    public static boolean isIndexPending() {\r
+        synchronized (indexPendings) {\r
+            return !indexPendings.isEmpty();\r
+        }\r
+    }\r
+\r
+    private static long totalWaitTime = 0;\r
+\r
+    public static void waitIndexPending() {\r
+        long startTime = PROFILE ? System.nanoTime() : 0;\r
+        boolean waited = false;\r
+        int time = 1;\r
+        synchronized (indexPendings) {\r
+            while (isIndexPending()) {\r
+                try {\r
+                    waited = true;\r
+                    indexPendings.wait(time++);\r
+                    if (time > 10) time = 10;\r
+                } catch (InterruptedException e) {\r
+                    Logger.defaultLogError(e);\r
+                }\r
+            }\r
+        }\r
+        if (PROFILE) {\r
+            if (waited) {\r
+                long endTime = System.nanoTime();\r
+                long waitTime = endTime - startTime;\r
+                totalWaitTime += waitTime;\r
+                System.out.println("Indexing wait time " + (waitTime*1e-6) + " ms (total " + (totalWaitTime*1e-6) + " ms)");\r
+            }\r
+        }\r
+    }\r
+\r
+    /**\r
+     * @param graph an active database write handle to prove one is in a write\r
+     *        transaction and wants to disable dependencies indexing for this\r
+     *        transaction only.\r
+     * @return previous value\r
+     */\r
+    public static boolean setDependenciesIndexingDisabled(WriteOnlyGraph graph, boolean disabled) {\r
+        if (graph == null)\r
+            throw new NullPointerException("null write graph");\r
+        // TODO: check that graph is valid once made possible\r
+        return dependenciesIndexingDisabled.getAndSet(disabled);\r
+    }\r
+\r
+    public static boolean resetDependenciesIndexingDisabled() {\r
+       return dependenciesIndexingDisabled.compareAndSet(true, false);\r
+    }\r
+\r
+    public static boolean isDependenciesIndexingDisabled() {\r
+       if (!useIndexing)\r
+               return true;\r
+        return dependenciesIndexingDisabled.get();\r
+    }\r
+    \r
+    public static void setDefaultDependenciesIndexingEnabled(boolean b) {\r
+       useIndexing = b;\r
+    }\r
+\r
+}\r