KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > core > storage > magicStore > MagicCluster


1 // You can redistribute this software and/or modify it under the terms of
2
// the Ozone Core License version 1 published by ozone-db.org.
3
//
4
// The original code and portions created by SMB are
5
// Copyright (C) 1997-@year@ by SMB GmbH. All rights reserved.
6
//
7
// $Id: MagicCluster.java,v 1.2 2004/01/10 21:40:24 per_nyfelt Exp $
8

9 package org.ozoneDB.core.storage.magicStore;
10
11 import java.io.Externalizable JavaDoc;
12 import java.io.File JavaDoc;
13 import java.io.IOException JavaDoc;
14 import java.io.ObjectInput JavaDoc;
15 import java.io.ObjectOutput JavaDoc;
16 import java.io.ObjectStreamException JavaDoc;
17 import org.ozoneDB.DxLib.DxArrayBag;
18 import org.ozoneDB.DxLib.DxCollection;
19 import org.ozoneDB.DxLib.DxHashMap;
20 import org.ozoneDB.DxLib.DxIterator;
21 import org.ozoneDB.DxLib.DxLong;
22 import org.ozoneDB.core.Lock;
23 import org.ozoneDB.core.MROWLock;
24 import org.ozoneDB.core.Permissions;
25 import org.ozoneDB.core.Transaction;
26 import org.ozoneDB.core.TransactionID;
27 import org.ozoneDB.core.storage.*;
28 import org.ozoneDB.util.LogWriter;
29
30
31
32 /**
33  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
34  * @author <a HREF="http://www.medium.net/">Medium.net</a>
35  * @author Leo Mekenkamp
36  * @author Per Nyfelt
37  * @version $Revision: 1.2 $Date: 2004/01/10 21:40:24 $
38  * We need to extend Cluster in wizardStore to be compatible with wizardStore
39  * note: if be abandon compatibility it should extend AbstractCluster
40  */

41 public final class MagicCluster extends org.ozoneDB.core.wizardStore.Cluster implements Externalizable JavaDoc /*, ActiveCacheable*/ {
42
43     protected final static long serialVersionUID = 2L;
44     protected final static byte subSerialVersionUID = 1;
45
46     protected transient MROWLock lock;
47
48     protected transient long lastTouched;
49
50     protected transient int bytesPerContainer;
51
52     protected long modTime;
53
54 // private transient ActiveCacheable.Delegator cacheDelegator;
55

56     /**
57      * Constructor to be used for Externalizable object serialisation.
58      */

59     public MagicCluster() {
60         this(null, null, null, 0);
61     }
62
63
64     public MagicCluster(ClusterID _clusterID, Permissions _permissions, MROWLock lock, int _bpc) {
65         // the env and clusterStore will be set by clusterStore
66
clusterID = _clusterID;
67         permissions = _permissions;
68         this.lock = lock;
69         bytesPerContainer = _bpc;
70         containers = new DxHashMap(1024);
71         if (lock != null) {
72             lock.setDebugInfo("clusterID=" + clusterID);
73         }
74 // cacheDelegator = new ActiveCacheable.Delegator();
75
}
76
77     public void addedTo(Cache addedTo, Object JavaDoc key) {
78 // cacheDelegator.addedTo(addedTo, key);
79
}
80
81     public void removedFrom(Cache removedFrom, Object JavaDoc key) {
82 // cacheDelegator.removedFrom(removedFrom, key);
83
}
84
85     public void delete() throws Exception JavaDoc {
86         File JavaDoc clusterFile = new File JavaDoc(clusterStore.basename(clusterID) + ClusterStore.POSTFIX_CLUSTER);
87         if (!clusterFile.delete()) {
88             throw new IOException JavaDoc("Could not delete cluster file " + clusterFile);
89         }
90     }
91
92
93     protected synchronized void unregister() {
94 // cacheDelegator.unregister();
95
}
96
97     protected void finalize() {
98         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
99             env.logWriter.newEntry(this, "---finalize(): cluster " + clusterID, LogWriter.DEBUG3);
100         }
101
102         // any lock levels >= READ has to be persistent
103
if (lock.level(null) >= Lock.LEVEL_READ) {
104             if (env.logWriter.hasTarget(LogWriter.DEBUG)) {
105                 env.logWriter.newEntry(this, " write lock to disk: " + clusterID, LogWriter.DEBUG);
106             }
107
108             try {
109                 ((ClusterStore)clusterStore).storeDataImmediately(lock(), clusterStore.basename(clusterID) + ClusterStore.POSTFIX_LOCK);
110             } catch (IOException JavaDoc e) {
111                 env.logWriter.newEntry(this, "could not write cluster lock " + clusterID, LogWriter.ERROR);
112             }
113         } else {
114             File JavaDoc lockFile = new File JavaDoc(clusterStore.basename(clusterID) + ClusterStore.POSTFIX_LOCK);
115             if (lockFile.exists()) {
116                 lockFile.delete();
117             }
118         }
119
120         // clusters with WRITE lock are supposed to be dirty
121
if (lock.level(null) > Lock.LEVEL_UPGRADE) {
122             if (env.logWriter.hasTarget(LogWriter.DEBUG)) {
123                 env.logWriter.newEntry(this, " write cluster: " + clusterID, LogWriter.DEBUG);
124             }
125
126             TransactionID taID = lock.getWriteLockingTransactionID();
127             if (taID == null) {
128                 env.logWriter.newEntry(this, "BUG: cluster is write locked but cannot find locker transaction id" + clusterID, LogWriter.ERROR);
129             }
130             try {
131                 ((ClusterStore)clusterStore).storeDataImmediately(this, clusterStore.basename(clusterID) + ClusterStore.POSTFIX_SEPARATOR + taID.value() + ClusterStore.POSTFIX_CLUSTER);
132             } catch (IOException JavaDoc e) {
133                 env.logWriter.newEntry(this, "could not write cluster lock " + clusterID, LogWriter.ERROR);
134             }
135         }
136
137         // mark this cluster to be not valid
138
setLock(null);
139
140         unregister();
141     }
142
143
144     public long modTime() {
145         return modTime;
146     }
147
148
149     /**
150      * Priority of this cluster to stay in the cluster cache. Low return value
151      * means low priority.
152      * @return Cache priority of the cluster.
153      */

154     public DxLong cachePriority() {
155         return new DxLong(lastTouched);
156     }
157
158
159     public synchronized void setCurrentSize(int byteSize) {
160         int containerCount = containers.count();
161         bytesPerContainer = containerCount > 0 ? byteSize / containerCount : clusterStore.currentBytesPerContainer();
162     }
163
164
165     public int size() {
166         return containers.count() * bytesPerContainer;
167     }
168
169
170     public ClusterID clusterID() {
171         return clusterID;
172     }
173
174
175     /**
176      * @return True if at least one container is currently invoked.
177      */

178     public boolean isInvoked() {
179         //FIXME: should be a bit in the status byte that is directly changed
180
// by clusters when they are changed
181
StorageObjectContainer container;
182         DxIterator it = containers.iterator();
183         while ((container = (StorageObjectContainer) it.next()) != null) {
184             if (container.isInvoked()) {
185                 return true;
186             }
187         }
188         return false;
189     }
190
191
192     public synchronized void touch() {
193         lastTouched = clusterStore.touchCount++;
194     }
195
196
197     /**
198      * Note: This method must not be synchronized.
199      *
200      * @param ta
201      */

202     public void updateLockLevel(Transaction ta) throws IOException JavaDoc {
203         if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {
204             env.logWriter.newEntry(this, "updateLockLevel(): " + clusterID, LogWriter.DEBUG2);
205             env.logWriter.newEntry(this, " lock: " + lock.level(ta), LogWriter.DEBUG2);
206         }
207     }
208
209
210     public void prepareCommit(Transaction ta) /*throws Exception*/ {
211         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
212             env.logWriter.newEntry(this, "prepareCommit()" + clusterID, LogWriter.DEBUG3);
213         }
214         if (lock.level(ta) > Lock.LEVEL_UPGRADE) {
215             synchronized (this) {
216                 modTime = System.currentTimeMillis();
217             }
218         }
219     }
220
221
222     public void commit(Transaction ta) throws IOException JavaDoc {
223         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
224             env.logWriter.newEntry(this, "commit()" + clusterID, LogWriter.DEBUG3);
225         }
226
227         if (true || lock != null) {
228             lock.release(ta);
229         } else {
230 // env.logWriter.newEntry( this, this+".commit(): lock="+lock+".", LogWriter.DEBUG3 );
231
throw new NullPointerException JavaDoc(this + ".commit(" + ta + "): lock=" + lock + ".");
232         }
233     }
234
235
236     public void abort(Transaction ta) throws IOException JavaDoc {
237         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
238             env.logWriter.newEntry(this, "abort()" + clusterID, LogWriter.DEBUG3);
239         }
240
241         if (true || lock != null) {
242             lock.release(ta);
243         } else {
244             throw new NullPointerException JavaDoc(this + ".abort(" + ta + "): lock=" + lock + ".");
245         }
246     }
247
248     public DxCollection allLockers() {
249         DxCollection lockerIDs = lock.lockerIDs();
250
251         DxArrayBag result = new DxArrayBag(lockerIDs.count());
252         DxIterator it = lockerIDs.iterator();
253         while (it.next() != null) {
254             result.add(env.transactionManager.taForID((TransactionID) it.object()));
255         }
256
257         return result;
258     }
259
260     public String JavaDoc toString() {
261         return "MagicCluster[id=" + clusterID + "]";
262     }
263
264     public Lock lock() {
265         return lock;
266     }
267
268     public void setLock(Lock to) {
269         //TODO: When can the lock be null and what is the significance of that?
270
if (to == null) {
271             if (env.logWriter.hasTarget(LogWriter.DEBUG)) {
272                 env.logWriter.newEntry(this, this + ".setLock(" + to + ") (oldLock=" + this.lock + ").", LogWriter.DEBUG);
273             }
274         }
275
276         this.lock = (MROWLock) to;
277     }
278
279     public void writeExternal(ObjectOutput JavaDoc out) throws IOException JavaDoc {
280 // // cannot use logwriter because of nullpointer exception
281
// if ((containers.count() == 0 && pinCount != 0) || (containers.count() > 0 && pinCount > 1)) {
282
// System.out.println("pincount for " + this + " not 1 while writing (" + pinCount + " for " + containers.count() + " containers)");
283
// }
284
// System.out.println ("cluster.writeExternal()...");
285
out.writeByte(subSerialVersionUID);
286         out.writeObject(clusterID);
287         out.writeObject(permissions);
288         out.writeLong(modTime);
289         // out.writeObject (lock);
290

291         out.writeInt(containers.count());
292         DxIterator it = containers.iterator();
293         StorageObjectContainer container;
294         while ((container = (StorageObjectContainer) it.next()) != null) {
295             // out.writeObject( container );
296
container.writeExternal(out);
297         }
298     }
299
300
301     public void readExternal(ObjectInput JavaDoc in) throws IOException JavaDoc, ObjectStreamException JavaDoc, ClassNotFoundException JavaDoc {
302         // System.out.println ("cluster.readExternal()...");
303
byte subSerialUID = in.readByte();
304         clusterID = (ClusterID) in.readObject();
305         permissions = (Permissions) in.readObject();
306         modTime = in.readLong();
307         // lock = (Lock)in.readObject();
308

309         int count = in.readInt();
310         for (int i = 0; i < count; i++) {
311             try {
312                 // MagicObjectContainer container = (MagicObjectContainer)in.readObject();
313
StorageObjectContainer container = new MagicObjectContainer();
314                 container.readExternal(in);
315                 container.setCluster(this);
316 // Env.currentEnv().getLogWriter().newEntry(this,this+".readExternal(): container.id()="+container.id()+".",LogWriter.DEBUG2);
317
containers.addForKey(container, container.id());
318             } catch (ObjectStreamException JavaDoc e) {
319                 if (env != null) {
320                     env.logWriter.newEntry(this, "ObjectStreamException for cluster " + clusterID + " at container #" + i + ": ", e, LogWriter.ERROR);
321                 } else {
322                     System.out.println("ObjectStreamException for cluster " + clusterID + " at container #" + i + ": " + e);
323                 }
324                 throw e;
325             }
326         }
327     }
328
329
330 }
331
Popular Tags