]> gerrit.simantics Code Review - simantics/platform.git/blob - 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
1 package org.simantics.db.service;\r
2 \r
3 import java.io.File;\r
4 import java.io.IOException;\r
5 import java.util.HashMap;\r
6 \r
7 import org.simantics.databoard.Bindings;\r
8 import org.simantics.databoard.Files;\r
9 import org.simantics.databoard.binding.Binding;\r
10 import org.simantics.databoard.parser.repository.DataValueRepository;\r
11 import org.simantics.db.exception.RuntimeDatabaseException;\r
12 \r
13 public class ClusterSets {\r
14 \r
15         //    final private static boolean DEBUG = false;\r
16 \r
17         private File writeDirectory;\r
18         final private String databaseId;\r
19         final private HashMap<Long, Long> clusterSets; // Maps cluster set resource id to last user cluster id in the cluster set.\r
20         final private HashMap<Long, Long> reverseMap;\r
21         private int refCount; // Reference counter for user of this class.\r
22         private boolean modified; // True if modified since last save.\r
23 \r
24         public void setWriteDirectory(File writeDirectory) {\r
25                 this.writeDirectory = writeDirectory;\r
26         }\r
27         \r
28         private File getFile1(File directory) {\r
29                 return new File(directory, "clusterSets." + this.databaseId + ".dat");\r
30         }\r
31 \r
32         private File getFile2(File directory) {\r
33                 return new File(directory, "clusterSets." + this.databaseId + ".dat.reverse");\r
34         }\r
35 \r
36         public ClusterSets(File readDirectory, File writeDirectory, String databaseId) {\r
37 \r
38                 try {\r
39 \r
40                         this.databaseId = databaseId;\r
41                         this.writeDirectory = writeDirectory;\r
42 \r
43                         readDirectory.mkdirs();\r
44 \r
45                         File file1 = getFile1(readDirectory);\r
46                         File file2 = getFile2(readDirectory);\r
47 \r
48                         this.refCount = 1;\r
49                         PersistentData pd, pd2;\r
50                         try {\r
51                                 pd = (PersistentData)Files.readFile(file1, PersistentData.BINDING);\r
52                         } catch (IOException e) {\r
53                                 // New file\r
54                                 pd = new PersistentData();\r
55                                 pd.values = new HashMap<Long, Long>();\r
56                                 Files.writeFile(file1, PersistentData.BINDING, pd);\r
57                         }\r
58                         try {\r
59                                 pd2 = (PersistentData)Files.readFile(file2, PersistentData.BINDING);\r
60                         } catch (IOException e) {\r
61                                 // New file\r
62                                 pd2 = new PersistentData();\r
63                                 pd2.values = new HashMap<Long, Long>();\r
64                                 Files.writeFile(file2, PersistentData.BINDING, pd2);\r
65                         }\r
66                         this.clusterSets = pd.values;\r
67                         this.reverseMap = pd2.values;\r
68                         this.modified = false;\r
69                 } catch (Exception e) {\r
70                         e.printStackTrace();\r
71                         throw new RuntimeDatabaseException("Failed to create ClusterSets.");\r
72                 }\r
73         }\r
74         public synchronized int inc() {\r
75                 return ++refCount;\r
76         }\r
77         public synchronized int dec() {\r
78                 return --refCount;\r
79         }\r
80         // Save is thread safe.\r
81         public void dispose() {\r
82                 try {\r
83                         // We still save changes even if transaction is not finished.\r
84                         // This is because we have no cancel mechanism for cluster (sets).\r
85                         save();\r
86                 } catch (IOException e) {\r
87                         e.printStackTrace();\r
88                         throw new RuntimeDatabaseException("Failed to save ClusterSets.");\r
89                 } \r
90         }\r
91         // clusterSets is not thread safe.\r
92         public synchronized boolean containsKey(long resourceId) {\r
93                 return clusterSets.containsKey(resourceId);\r
94         }\r
95         public synchronized Long get(Long resourceId) {\r
96                 return clusterSets.get(resourceId);\r
97         }\r
98         public synchronized void put(long resourceId, long clusterId) {\r
99                 clusterSets.put(resourceId, clusterId);\r
100                 reverseMap.put(clusterId, resourceId);\r
101                 modified = true;\r
102         }\r
103         public synchronized Long getClusterSet(Long clusterId) {\r
104                 return reverseMap.get(clusterId);\r
105         }\r
106         public void clear() {\r
107                 \r
108                 for(Long key : clusterSets.keySet())\r
109                         clusterSets.put(key, -1L);\r
110                 \r
111                 touch();\r
112                 \r
113         }\r
114         public synchronized void touch() {\r
115                 modified = true;\r
116         }\r
117         public synchronized void save() throws IOException {\r
118 \r
119                 if (!modified)\r
120                         return;\r
121                 \r
122                 writeDirectory.mkdirs();\r
123                 File file1 = getFile1(writeDirectory);\r
124                 File file2 = getFile2(writeDirectory);\r
125                 PersistentData pd = new PersistentData();\r
126                 pd.values = clusterSets;\r
127                 Files.writeFile(file1, PersistentData.BINDING, pd);\r
128                 pd = new PersistentData();\r
129                 pd.values = reverseMap;\r
130                 Files.writeFile(file2, PersistentData.BINDING, pd);\r
131                 modified = false;\r
132 \r
133         }\r
134         static public class PersistentData {\r
135                 final public static Binding BINDING = Bindings.getBindingUnchecked(PersistentData.class);\r
136                 //        public TreeMap<Long, Long> values;\r
137                 public HashMap<Long, Long> values;\r
138                 public static void main(String[] args) throws Exception {\r
139                         System.err.println("" + BINDING.type().toSingleLineString());\r
140                         PersistentData pd = new PersistentData();\r
141                         //         pd.values = new TreeMap<Long, Long>();\r
142                         pd.values = new HashMap<Long, Long>();\r
143                         for (long i=0; i<10; ++i)\r
144                                 pd.values.put(i, i);\r
145                         BINDING.printValue(pd, System.err, new DataValueRepository(), true);\r
146                 }\r
147         }\r
148         \r
149 }\r