KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > ozoneDB > core > storage > gammaStore > GammaTransaction


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
// Copyright (C) 2003-@year@, Leo Mekenkamp. All rights reserved.
5
//
6
// $Id: GammaTransaction.java,v 1.3 2004/01/03 10:39:41 per_nyfelt Exp $
7

8 package org.ozoneDB.core.storage.gammaStore;
9
10 import java.io.IOException JavaDoc;
11 import java.io.ObjectOutputStream JavaDoc;
12 import java.util.LinkedHashMap JavaDoc;
13 import java.util.Map JavaDoc;
14 import java.util.Properties JavaDoc;
15 import org.ozoneDB.ObjectNotFoundException;
16 import org.ozoneDB.OzoneInternalException;
17 import org.ozoneDB.OzoneObjectException;
18 import org.ozoneDB.OzoneRemoteException;
19 import org.ozoneDB.TransactionException;
20 import org.ozoneDB.core.Env;
21 import org.ozoneDB.core.Lock;
22 import org.ozoneDB.core.ObjectContainer;
23 import org.ozoneDB.core.ObjectID;
24 import org.ozoneDB.core.PermissionError;
25 import org.ozoneDB.core.Transaction;
26 import org.ozoneDB.core.TransactionError;
27 import org.ozoneDB.core.User;
28 import org.ozoneDB.core.storage.Cache;
29 import org.ozoneDB.core.storage.FixedSizeCache;
30 import org.ozoneDB.core.storage.WeakReferenceCache;
31 import org.ozoneDB.util.LogWriter;
32
33 /**
34  * @author <a HREF="mailto:leoATmekenkampD0Tcom">Leo Mekenkamp (mind the anti sp@m)</a>
35  * @version $Id: GammaTransaction.java,v 1.3 2004/01/03 10:39:41 per_nyfelt Exp $
36  */

37 public class GammaTransaction extends Transaction {
38     
39     // should be configurable settings
40
private static final int FIXME_MAX_OBJECT_IDS = 250;
41     
42     private static final float FIXME_LOADFACTOR_OBJECT_IDS = 0.75F;
43     
44     private static final String JavaDoc LOGPOSTFIX = ".txlog";
45     
46     private GammaStore gammaStore;
47     
48     private Storage logStorage;
49     
50     /**
51      * Transactions have their own private cache. Should be a WeakReferenceCache
52      * because GammaStore has the last say in which objects should be cached.
53      * Having its own cache means this tx can find out when containers are no
54      * longer in memory. When a container is swapped out it can (through a
55      * shadow remover specified in this tx) write its object id to the log of
56      * this tx.
57      */

58     private Cache containerCache = new FixedSizeCache(new Properties JavaDoc(), "") {
59         
60         public Object JavaDoc remove(Object JavaDoc key) {
61             GammaContainer result = (GammaContainer) super.remove(key);
62 // try {
63
// getLogStorage().writeObject(result.getObjectId());
64
// } catch (IOException e) {
65
// throw new OzoneInternalException("could not write object id " + result.getObjectId() + " to log stream " + getLogStream(), e);
66
// }
67
return result;
68         }
69         
70     };
71
72     /**
73      * An unlimited number of objects might be changed during any transaction.
74      * It is impossible to keep track of all object ids in memory, instead this
75      * <code>LinkedHashMap</code> is used to keep the MRU in memory, while
76      * writing the LRU out to disk. We could use a <code>LinkedHashSet</code>
77      * instead (since we only use the keys, and not the values
78      */

79     private LinkedHashMap JavaDoc changedObjectIds;
80     
81     public GammaTransaction(GammaStore gammaStore, StorageFactory logStorageFactory, Env env, User owner) {
82         super(env, owner);
83         try {
84             setGammaStore(gammaStore);
85             setLogStorage(logStorageFactory.createStorage(logFilename()));
86         } catch (IOException JavaDoc e) {
87             throw new OzoneInternalException("could not create transaction", e);
88         }
89         changedObjectIds = new LinkedHashMap JavaDoc(FIXME_MAX_OBJECT_IDS, FIXME_LOADFACTOR_OBJECT_IDS, true) {
90             public boolean removeEldestEntry(Map.Entry JavaDoc eldest) {
91                 
92                 // use -1 to make sure rehashing never takes place
93
boolean result = size() >= FIXME_MAX_OBJECT_IDS - 1;
94                 if (result) {
95                     ObjectID objectID = (ObjectID) eldest.getValue();
96                     try {
97                         getLogStorage().writeLong(objectID.value());
98                     } catch (IOException JavaDoc e) {
99                         throw new OzoneInternalException("could not write object id", e);
100                     }
101                 }
102                 return result;
103             }
104         };
105     }
106
107     String JavaDoc logFilename() {
108         String JavaDoc result = Long.toString(taID().value()) + LOGPOSTFIX;
109         return result;
110     }
111     
112     /**
113      * Blatantly stolen from <code>org.ozoneDB.core.Transaction</code>. Removed
114      * code dependent on WizardStore
115      */

116     protected ObjectContainer acquireContainer(ObjectContainer container, int lockLevel) throws PermissionError, TransactionException, TransactionError, IOException JavaDoc, ObjectNotFoundException, ClassNotFoundException JavaDoc {
117
118         if (stopped == true) {
119             throw new TransactionException("Stopped.", TransactionException.STOPPED);
120         }
121
122         maxLockLevel = lockLevel > maxLockLevel ? lockLevel : maxLockLevel;
123
124         acquireCount++;
125
126         // this should help to let the following code execute without
127
// interrupt and so ensure that the container that we retrieve from
128
// the store is not deactivated while this method is running
129
// Thread.currentThread().yield();
130

131         // transaktion als blockiert markieren (kante in lock-graphen einfuegen);
132
// vor deadlock-erkennung: es werden auch deadlocks mit
133
// transaktionen erkannt, die selber erstmal auf deadlock checken
134
// aber auf keinem fall zuwenige (race-cond. zwischen deadlock-pruefung
135
// und lock setzen)
136
blocker = container.id();
137
138         // this may happen when the container was deactivated between
139
// acquireObject() and this point; I'm not sure what to do here
140

141         // But I (Xuân Baldauf, Medium.net) am (partly):
142
// If our caller is acquireContainer(), the container is pinned and thus may not be deactived inbetween.
143
// If our caller is createObject(), the container is pinned and thus may not be deactived inbetween.
144
if (container.lock() == null) {
145             throw new IllegalStateException JavaDoc("Container was wrongly deactivated. Increasing heap memory of the JVM may help.");
146         }
147
148         // try to aquire the lock of the container; wait until the locks is
149
// successfully aquired
150
int prevLevel = container.lock().tryAcquire(this, lockLevel);
151
152         if (prevLevel == Lock.NOT_ACQUIRED) {
153             synchronized (this) {
154                 while (prevLevel == Lock.NOT_ACQUIRED) {
155                     try {
156                         if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {
157                             env.logWriter.newEntry(this, toString() + " blocked by lock " + container.lock() + "...", LogWriter.DEBUG2);
158                         }
159
160                         wait();
161
162                         if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {
163                             env.logWriter.newEntry(this, toString() + " checking lock again...", LogWriter.DEBUG2);
164                         }
165                     } catch (Exception JavaDoc e) {
166                         // do nothing; just proceed...
167
}
168
169                     /*
170                         We have two cases:
171                         (1) We are called by acquireObject()
172                         (2) We are not called by acquireObject()
173
174                         In case (1), we do not need to reload, because the object is pinned.
175                         In case (2), we never come to this code location, because in this case, the objects are freshly created and thus never locked.
176
177                         Thus, we never need to reload.
178
179                         Oh, the reasoning above does not work out. If a cluster is pinned,
180                         it still may be aborted and thus need to reload. But maybe then the
181                         "pinned" concept is mood. Maybe pinned clusters which are arborted
182                         should be reloaded immediately.
183                     */

184
185                     // since the container was maybe deactivated while waiting we
186
// reload it here again
187
ObjectContainer newContainer = env.storeManager.containerForID(this, blocker);
188
189                     if (container == null) {
190                         throw new ObjectNotFoundException("No such object.");
191                     }
192
193                     // throw an exception if we are forced to abort because of a deadlock
194
container.lock().checkDeadlock(this);
195
196                     prevLevel = container.lock().tryAcquire(this, lockLevel);
197                 }
198             }
199         }
200
201         if (false) {
202             env.logWriter.newEntry(this, toString() + ".acquireContainer(" + blocker + "): successful.", LogWriter.DEBUG);
203         }
204
205         // transaction is no longer blocked
206
blocker = null;
207
208
209         // after acquiring the lock we update the lock level of the container
210
if (prevLevel < lockLevel) {
211             if (owner == null) {
212                 throw new PermissionError("No such user.");
213             }
214             if (!env.userManager.checkPermission(owner, container, lockLevel)) {
215                 throw new PermissionError("User does not have proper access rights.");
216             }
217
218             env.storeManager.updateLockLevel(this, container);
219         }
220         container.touch();
221         
222         GammaContainer gammaContainer = (GammaContainer) container;
223         getContainerCache().put(gammaContainer.getObjectId(), gammaContainer);
224
225         return container;
226     }
227
228     // private so it can be inlined
229
private GammaStore getGammaStore() {
230         return gammaStore;
231     }
232     
233     // private so it can be inlined
234
private void setGammaStore(GammaStore gammaStore) {
235         this.gammaStore = gammaStore;
236     }
237     
238     Cache getContainerCache() {
239         return containerCache;
240     }
241     
242     public ObjectContainer createObject(String JavaDoc className, int access, String JavaDoc name, String JavaDoc sig, Object JavaDoc[] args, ObjectID id) throws Exception JavaDoc, OzoneObjectException {
243         GammaContainer result;
244         
245         result = (GammaContainer) super.createObject(className, access, name, sig, args, id);
246         getContainerCache().put(result.getObjectId(), result);
247         return result;
248     }
249     
250     /** @param id
251      * @param methodName
252      * @param sig
253      * @param lockLevel
254      * @return the result of the invocation
255      *
256      */

257     public Object JavaDoc invokeObject(ObjectID id, String JavaDoc methodName, String JavaDoc sig, Object JavaDoc[] args, int lockLevel) throws Exception JavaDoc, OzoneObjectException {
258         Object JavaDoc retValue;
259         
260         retValue = super.invokeObject(id, methodName, sig, args, lockLevel);
261         return retValue;
262     }
263     
264     public Object JavaDoc invokeObject(ObjectID id, int methodIndex, Object JavaDoc[] args, int lockLevel) throws Exception JavaDoc, OzoneObjectException {
265         Object JavaDoc retValue;
266         
267         retValue = super.invokeObject(id, methodIndex, args, lockLevel);
268         return retValue;
269     }
270     
271     public void nameObject(ObjectID id, String JavaDoc name) throws Exception JavaDoc {
272         super.nameObject(id, name);
273     }
274     
275     public void deleteObject(ObjectID id) throws ObjectNotFoundException, IOException JavaDoc, ClassNotFoundException JavaDoc, TransactionException, TransactionError, OzoneRemoteException, OzoneInternalException, OzoneObjectException {
276         super.deleteObject(id);
277     }
278     
279     Storage getLogStorage() {
280         return logStorage;
281     }
282     
283     private void setLogStorage(Storage logStorage) {
284         this.logStorage = logStorage;
285     }
286     
287 }
288
Popular Tags