1 package org.simantics.db.service;
\r
4 import java.io.IOException;
\r
5 import java.util.HashMap;
\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
13 public class ClusterSets {
\r
15 // final private static boolean DEBUG = false;
\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
24 public void setWriteDirectory(File writeDirectory) {
\r
25 this.writeDirectory = writeDirectory;
\r
28 private File getFile1(File directory) {
\r
29 return new File(directory, "clusterSets." + this.databaseId + ".dat");
\r
32 private File getFile2(File directory) {
\r
33 return new File(directory, "clusterSets." + this.databaseId + ".dat.reverse");
\r
36 public ClusterSets(File readDirectory, File writeDirectory, String databaseId) {
\r
40 this.databaseId = databaseId;
\r
41 this.writeDirectory = writeDirectory;
\r
43 readDirectory.mkdirs();
\r
45 File file1 = getFile1(readDirectory);
\r
46 File file2 = getFile2(readDirectory);
\r
49 PersistentData pd, pd2;
\r
51 pd = (PersistentData)Files.readFile(file1, PersistentData.BINDING);
\r
52 } catch (IOException e) {
\r
54 pd = new PersistentData();
\r
55 pd.values = new HashMap<Long, Long>();
\r
56 Files.writeFile(file1, PersistentData.BINDING, pd);
\r
59 pd2 = (PersistentData)Files.readFile(file2, PersistentData.BINDING);
\r
60 } catch (IOException e) {
\r
62 pd2 = new PersistentData();
\r
63 pd2.values = new HashMap<Long, Long>();
\r
64 Files.writeFile(file2, PersistentData.BINDING, pd2);
\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
74 public synchronized int inc() {
\r
77 public synchronized int dec() {
\r
80 // Save is thread safe.
\r
81 public void dispose() {
\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
86 } catch (IOException e) {
\r
87 e.printStackTrace();
\r
88 throw new RuntimeDatabaseException("Failed to save ClusterSets.");
\r
91 // clusterSets is not thread safe.
\r
92 public synchronized boolean containsKey(long resourceId) {
\r
93 return clusterSets.containsKey(resourceId);
\r
95 public synchronized Long get(Long resourceId) {
\r
96 return clusterSets.get(resourceId);
\r
98 public synchronized void put(long resourceId, long clusterId) {
\r
99 clusterSets.put(resourceId, clusterId);
\r
100 reverseMap.put(clusterId, resourceId);
\r
103 public synchronized Long getClusterSet(Long clusterId) {
\r
104 return reverseMap.get(clusterId);
\r
106 public void clear() {
\r
108 for(Long key : clusterSets.keySet())
\r
109 clusterSets.put(key, -1L);
\r
114 public synchronized void touch() {
\r
117 public synchronized void save() throws IOException {
\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
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