]> gerrit.simantics Code Review - simantics/platform.git/blobdiff - bundles/org.simantics.db/src/org/simantics/db/service/ClusterSets.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.db / src / org / simantics / db / service / ClusterSets.java
diff --git a/bundles/org.simantics.db/src/org/simantics/db/service/ClusterSets.java b/bundles/org.simantics.db/src/org/simantics/db/service/ClusterSets.java
new file mode 100644 (file)
index 0000000..8a4e058
--- /dev/null
@@ -0,0 +1,149 @@
+package org.simantics.db.service;\r
+\r
+import java.io.File;\r
+import java.io.IOException;\r
+import java.util.HashMap;\r
+\r
+import org.simantics.databoard.Bindings;\r
+import org.simantics.databoard.Files;\r
+import org.simantics.databoard.binding.Binding;\r
+import org.simantics.databoard.parser.repository.DataValueRepository;\r
+import org.simantics.db.exception.RuntimeDatabaseException;\r
+\r
+public class ClusterSets {\r
+\r
+       //    final private static boolean DEBUG = false;\r
+\r
+       private File writeDirectory;\r
+       final private String databaseId;\r
+       final private HashMap<Long, Long> clusterSets; // Maps cluster set resource id to last user cluster id in the cluster set.\r
+       final private HashMap<Long, Long> reverseMap;\r
+       private int refCount; // Reference counter for user of this class.\r
+       private boolean modified; // True if modified since last save.\r
+\r
+       public void setWriteDirectory(File writeDirectory) {\r
+               this.writeDirectory = writeDirectory;\r
+       }\r
+       \r
+       private File getFile1(File directory) {\r
+               return new File(directory, "clusterSets." + this.databaseId + ".dat");\r
+       }\r
+\r
+       private File getFile2(File directory) {\r
+               return new File(directory, "clusterSets." + this.databaseId + ".dat.reverse");\r
+       }\r
+\r
+       public ClusterSets(File readDirectory, File writeDirectory, String databaseId) {\r
+\r
+               try {\r
+\r
+                       this.databaseId = databaseId;\r
+                       this.writeDirectory = writeDirectory;\r
+\r
+                       readDirectory.mkdirs();\r
+\r
+                       File file1 = getFile1(readDirectory);\r
+                       File file2 = getFile2(readDirectory);\r
+\r
+                       this.refCount = 1;\r
+                       PersistentData pd, pd2;\r
+                       try {\r
+                               pd = (PersistentData)Files.readFile(file1, PersistentData.BINDING);\r
+                       } catch (IOException e) {\r
+                               // New file\r
+                               pd = new PersistentData();\r
+                               pd.values = new HashMap<Long, Long>();\r
+                               Files.writeFile(file1, PersistentData.BINDING, pd);\r
+                       }\r
+                       try {\r
+                               pd2 = (PersistentData)Files.readFile(file2, PersistentData.BINDING);\r
+                       } catch (IOException e) {\r
+                               // New file\r
+                               pd2 = new PersistentData();\r
+                               pd2.values = new HashMap<Long, Long>();\r
+                               Files.writeFile(file2, PersistentData.BINDING, pd2);\r
+                       }\r
+                       this.clusterSets = pd.values;\r
+                       this.reverseMap = pd2.values;\r
+                       this.modified = false;\r
+               } catch (Exception e) {\r
+                       e.printStackTrace();\r
+                       throw new RuntimeDatabaseException("Failed to create ClusterSets.");\r
+               }\r
+       }\r
+       public synchronized int inc() {\r
+               return ++refCount;\r
+       }\r
+       public synchronized int dec() {\r
+               return --refCount;\r
+       }\r
+       // Save is thread safe.\r
+       public void dispose() {\r
+               try {\r
+                       // We still save changes even if transaction is not finished.\r
+                       // This is because we have no cancel mechanism for cluster (sets).\r
+                       save();\r
+               } catch (IOException e) {\r
+                       e.printStackTrace();\r
+                       throw new RuntimeDatabaseException("Failed to save ClusterSets.");\r
+               } \r
+       }\r
+       // clusterSets is not thread safe.\r
+       public synchronized boolean containsKey(long resourceId) {\r
+               return clusterSets.containsKey(resourceId);\r
+       }\r
+       public synchronized Long get(Long resourceId) {\r
+               return clusterSets.get(resourceId);\r
+       }\r
+       public synchronized void put(long resourceId, long clusterId) {\r
+               clusterSets.put(resourceId, clusterId);\r
+               reverseMap.put(clusterId, resourceId);\r
+               modified = true;\r
+       }\r
+       public synchronized Long getClusterSet(Long clusterId) {\r
+               return reverseMap.get(clusterId);\r
+       }\r
+       public void clear() {\r
+               \r
+               for(Long key : clusterSets.keySet())\r
+                       clusterSets.put(key, -1L);\r
+               \r
+               touch();\r
+               \r
+       }\r
+       public synchronized void touch() {\r
+               modified = true;\r
+       }\r
+       public synchronized void save() throws IOException {\r
+\r
+               if (!modified)\r
+                       return;\r
+               \r
+               writeDirectory.mkdirs();\r
+               File file1 = getFile1(writeDirectory);\r
+               File file2 = getFile2(writeDirectory);\r
+               PersistentData pd = new PersistentData();\r
+               pd.values = clusterSets;\r
+               Files.writeFile(file1, PersistentData.BINDING, pd);\r
+               pd = new PersistentData();\r
+               pd.values = reverseMap;\r
+               Files.writeFile(file2, PersistentData.BINDING, pd);\r
+               modified = false;\r
+\r
+       }\r
+       static public class PersistentData {\r
+               final public static Binding BINDING = Bindings.getBindingUnchecked(PersistentData.class);\r
+               //        public TreeMap<Long, Long> values;\r
+               public HashMap<Long, Long> values;\r
+               public static void main(String[] args) throws Exception {\r
+                       System.err.println("" + BINDING.type().toSingleLineString());\r
+                       PersistentData pd = new PersistentData();\r
+                       //         pd.values = new TreeMap<Long, Long>();\r
+                       pd.values = new HashMap<Long, Long>();\r
+                       for (long i=0; i<10; ++i)\r
+                               pd.values.put(i, i);\r
+                       BINDING.printValue(pd, System.err, new DataValueRepository(), true);\r
+               }\r
+       }\r
+       \r
+}\r