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