KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > myoodb > core > storage > Cluster


1 ///////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright (C) 2003-@year@ by Thomas M. Hazel, MyOODB (www.myoodb.org)
4
//
5
// All Rights Reserved
6
//
7
// This program is free software; you can redistribute it and/or modify
8
// it under the terms of the GNU General Public License and GNU Library
9
// General Public License as published by the Free Software Foundation;
10
// either version 2, or (at your option) any later version.
11
//
12
// This program is distributed in the hope that it will be useful,
13
// but WITHOUT ANY WARRANTY; without even the implied warranty of
14
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
// GNU General Public License and GNU Library General Public License
16
// for more details.
17
//
18
// You should have received a copy of the GNU General Public License
19
// and GNU Library General Public License along with this program; if
20
// not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
21
// MA 02139, USA.
22
//
23
///////////////////////////////////////////////////////////////////////////////
24
package org.myoodb.core.storage;
25
26 import java.io.*;
27
28 import org.myoodb.util.*;
29 import org.myoodb.core.*;
30
31 public final class Cluster implements Externalizable, AbstractCluster
32 {
33     private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(Cluster.class);
34
35     private AbstractLock m_lock;
36     private AbstractObjectContainer m_container;
37
38     public static File getMostCurrentCluster(String JavaDoc basename, Identifier objectId)
39     {
40         File current = new File(basename + ClusterStore.SUFFIX_CLUSTER);
41
42         final String JavaDoc strId = objectId.toString();
43         final String JavaDoc strIdWithSuffix = strId + ClusterStore.SUFFIX_SEPARATOR;
44         final String JavaDoc strIdClusterPath = ClusterStore.getDirectoryName(strId, objectId.isRoot());
45
46         FilenameFilter clusterFilter = new FilenameFilter()
47         {
48             public boolean accept(File dir, String JavaDoc name)
49             {
50                 return (name.startsWith(strIdWithSuffix) == true) && (name.endsWith(ClusterStore.SUFFIX_TEMP) == false);
51             }
52         };
53
54         long lastTX = -1;
55         File file = new File(strIdClusterPath);
56         String JavaDoc[] fileList = file.list(clusterFilter);
57         for (int i = 0; i < fileList.length; i++)
58         {
59             String JavaDoc[] tokens = fileList[i].split("\\.");
60
61             if (tokens.length == 3)
62             {
63                 long tmpTX = Long.parseLong(tokens[1]);
64
65                 if (tmpTX > lastTX)
66                 {
67                     current = new File(strIdClusterPath + File.separator + fileList[i]);
68                     lastTX = tmpTX;
69                 }
70             }
71         }
72
73         return current;
74     }
75
76     public static void delete(Identifier id) throws IOException
77     {
78         File file = new File(ClusterStore.getBasename(id) + ClusterStore.SUFFIX_CLUSTER);
79
80         if (file.exists() == true)
81         {
82             org.myoodb.core.FileHelper.delete(file);
83         }
84
85         // If nothing is left in the directory, delete it
86
File dfile = new File(ClusterStore.getDirectoryName(id.toString(), id.isRoot()));
87         String JavaDoc[] files = dfile.list();
88
89         if ((files != null) && (files.length == 0))
90         {
91             org.myoodb.core.FileHelper.delete(dfile);
92         }
93     }
94
95     public Cluster()
96     {
97     }
98
99     public Cluster(AbstractObjectContainer container, AbstractLock lock)
100     {
101         m_lock = lock;
102         setContainer(container);
103     }
104
105     protected void writeChild(AbstractTransaction tx) throws IOException
106     {
107         String JavaDoc basename = ClusterStore.getBasename(getObjectId());
108
109         File child = new File(basename +
110                               ClusterStore.SUFFIX_SEPARATOR +
111                               tx.getTransactionIdentifier() +
112                               ClusterStore.SUFFIX_CHILD);
113
114         File parent = getMostCurrentCluster(basename, getObjectId());
115
116         InputStream in = null;
117         OutputStream out = null;
118         try
119         {
120             in = new FileInputStream(parent);
121             out = new FileOutputStream(child);
122
123             int offset = 0;
124             int size = in.available();
125             byte[] buffer = new byte[in.available()];
126
127             while (offset < size)
128             {
129                 int bytesRead = in.read(buffer, offset, (size - offset));
130                 if (bytesRead == -1)
131                 {
132                     break;
133                 }
134
135                 out.write(buffer, offset, (size - offset));
136                 offset += bytesRead;
137             }
138         }
139         finally
140         {
141             if (in != null)
142             {
143                 in.close();
144             }
145             if (out != null)
146             {
147                 out.close();
148             }
149         }
150     }
151
152     protected void commitChild(AbstractTransaction tx) throws IOException
153     {
154         String JavaDoc basename = ClusterStore.getBasename(getObjectId());
155
156         File temp = new File(basename +
157                              ClusterStore.SUFFIX_SEPARATOR +
158                              tx.getTransactionIdentifier() +
159                              ClusterStore.SUFFIX_TEMP);
160
161         File child = new File(basename +
162                               ClusterStore.SUFFIX_SEPARATOR +
163                               tx.getTransactionIdentifier() +
164                               ClusterStore.SUFFIX_CHILD);
165
166         if (temp.exists() == true)
167         {
168             org.myoodb.core.FileHelper.delete(temp);
169         }
170
171         if (child.renameTo(temp) == false)
172         {
173             throw new IOException("Unable to rename \"child\" file to \"temp\":" + child + " " + temp + " " + tx);
174         }
175
176         File parent = getMostCurrentCluster(basename, getObjectId());
177
178         if (parent.exists() == true)
179         {
180             org.myoodb.core.FileHelper.delete(parent);
181         }
182
183         if (temp.renameTo(parent) == false)
184         {
185             throw new IOException("Unable to rename \"temp\" file to \"parent\":" + temp + " " + parent + " " + tx);
186         }
187     }
188
189     protected void deleteChild(AbstractTransaction tx) throws IOException
190     {
191         String JavaDoc basename = ClusterStore.getBasename(getObjectId());
192
193         File child = new File(basename +
194                               ClusterStore.SUFFIX_SEPARATOR +
195                               tx.getTransactionIdentifier() +
196                               ClusterStore.SUFFIX_CHILD);
197
198         if (child.exists() == true)
199         {
200             org.myoodb.core.FileHelper.delete(child);
201         }
202     }
203
204     protected Identifier getObjectId()
205     {
206         return m_container.getObjectId();
207     }
208
209     public AbstractLock getLock()
210     {
211         return m_lock;
212     }
213
214     public void setLock(AbstractLock lock)
215     {
216         m_lock = lock;
217     }
218
219     public void setContainer(AbstractObjectContainer container)
220     {
221        m_container = container;
222        m_container.setCluster(this);
223     }
224
225     public AbstractObjectContainer getContainer()
226     {
227         return m_container;
228     }
229
230     public void setAssociatedTransaction(AbstractTransaction tx) throws IOException
231     {
232         if (tx.getTransactionType() == AbstractTransaction.EXPLICIT_TRANSACTION)
233         {
234             writeChild(tx);
235         }
236     }
237
238     public void commit(AbstractTransaction tx) throws IOException
239     {
240         if (tx.getStagingTransactionFlag() == false)
241         {
242             if (tx.getTransactionType() == AbstractTransaction.EXPLICIT_TRANSACTION)
243             {
244                 commitChild(tx);
245             }
246
247             if (tx.isExplicitPiggyBack() == false)
248             {
249                 m_lock.release(tx);
250             }
251         }
252     }
253
254     public void abort(AbstractTransaction tx) throws IOException
255     {
256        if (tx.getTransactionType() == AbstractTransaction.EXPLICIT_TRANSACTION)
257        {
258            deleteChild(tx);
259        }
260
261        m_lock.release(tx);
262     }
263
264     public boolean delete(AbstractTransaction tx) throws IOException
265     {
266         boolean isBase = false;
267
268         if (tx.getStagingTransactionFlag() == false)
269         {
270             String JavaDoc basename = ClusterStore.getBasename(getObjectId());
271
272             File child = new File(basename +
273                                   ClusterStore.SUFFIX_SEPARATOR +
274                                   tx.getTransactionIdentifier() +
275                                   ClusterStore.SUFFIX_CHILD);
276
277             File base = new File(basename + ClusterStore.SUFFIX_CLUSTER);
278
279             if (child.equals(base) == true)
280             {
281                 isBase = true;
282             }
283
284             if (child.exists() == true)
285             {
286                 org.myoodb.core.FileHelper.delete(child);
287             }
288
289             // If nothing is left in the directory, delete it
290
File dfile = new File(ClusterStore.getDirectoryName(getObjectId().toString(), getObjectId().isRoot()));
291             String JavaDoc[] files = dfile.list();
292
293             if ((files != null) && (files.length == 0))
294             {
295                 org.myoodb.core.FileHelper.delete(dfile);
296             }
297         }
298
299         return isBase;
300     }
301
302     public void read(String JavaDoc file) throws IOException, ClassNotFoundException JavaDoc
303     {
304         ObjectInputStream in = new FastObjectInputStream(new BufferedInputStream(new FileInputStream(file)));
305
306         try
307         {
308             readExternal(in);
309         }
310         finally
311         {
312             in.close();
313         }
314     }
315
316     public void write(String JavaDoc filename) throws IOException
317     {
318         java.util.ConcurrentModificationException JavaDoc globalError = null;
319
320         for (int i = 0; i < ClusterStore.CONCURRENCY_RETRY; i++)
321         {
322             try
323             {
324                 ObjectOutputStream out = new FastObjectOutputStream(new BufferedOutputStream(new FileOutputStream(filename)));
325
326                 try
327                 {
328                     writeExternal(out);
329                     globalError = null;
330                     break;
331                 }
332                 finally
333                 {
334                     out.close();
335                 }
336             }
337             catch (java.util.ConcurrentModificationException JavaDoc e)
338             {
339                 LOGGER.warn(null, e);
340
341                 try
342                 {
343                     Thread.sleep(100);
344                 }
345                 catch (java.lang.InterruptedException JavaDoc ee)
346                 {
347                     // nothing to do
348
}
349
350                 globalError = e;
351             }
352         }
353
354         if (globalError != null)
355         {
356             throw globalError;
357         }
358     }
359
360     public void write() throws IOException
361     {
362         write(ClusterStore.getBasename(getObjectId()) + ClusterStore.SUFFIX_CLUSTER);
363     }
364
365     public void writeExternal(ObjectOutput out) throws IOException
366     {
367         out.writeObject(m_lock);
368         out.writeObject(m_container);
369     }
370
371     public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException JavaDoc
372     {
373         m_lock = (AbstractLock) in.readObject();
374         setContainer((AbstractObjectContainer) in.readObject());
375     }
376 }
377
Popular Tags