KickJava   Java API By Example, From Geeks To Geeks.

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


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: MagicStore.java,v 1.8 2004/01/22 07:48:59 leomekenkamp Exp $
8

9 package org.ozoneDB.core.storage.magicStore;
10
11 import java.io.*;
12 import java.util.Iterator JavaDoc;
13 import java.util.Set JavaDoc;
14
15 import org.ozoneDB.DxLib.*;
16 import org.ozoneDB.*;
17 import org.ozoneDB.io.stream.ResolvingObjectInputStream;
18 import org.ozoneDB.core.*;
19 import org.ozoneDB.core.storage.ClusterID;
20 import org.ozoneDB.core.storage.Cluster;
21 import org.ozoneDB.core.storage.StorageObjectContainer;
22 import org.ozoneDB.util.LogWriter;
23
24
25 /**
26  * @author <a HREF="http://www.softwarebuero.de/">SMB</a>
27  * @author <a HREF="http://www.medium.net/">Medium.net</a>
28  * @author Leo Mekenkamp
29  * @author Per Nyfelt
30  * @version $Revision: 1.8 $Date: 2004/01/22 07:48:59 $
31  */

32 public final class MagicStore
33         extends ServerComponent
34         implements StoreManager {
35
36     protected final static String JavaDoc ID_TABLE_NAME = "idTable.wizard";
37
38     protected final static String JavaDoc NAME_TABLE_NAME = "nameTable.wizard";
39
40     protected final static String JavaDoc COMMIT_FLAG_NAME = "commitflag.wizard";
41
42     /**
43      * Maps ObjectIDs to ClusterIDs
44      */

45     protected DxMap idTable;
46
47     /**
48      * Maps names to ObjectIDs
49      */

50     protected DxMap nameTable;
51
52     protected ClusterStore clusterStore;
53
54     /**
55      The garbage collector. It should be notified in the event
56      <UL>
57      <LI>that a formerly unnamed object receives a name.</LI>
58      <LI>that an object is freshly created</LI>
59      </LI>
60      */

61     protected GarbageCollector garbageCollector;
62
63     public MagicStore(Env env) {
64         super(env);
65     }
66
67
68     public synchronized void init(Env _env) {
69         env = _env;
70
71         int idTableBufferSize = env.config.intProperty(Setup.WS_TABLE_BUFF_SIZE, -1);
72         int idTableCacheSize = env.config.intProperty(Setup.WS_TABLE_CACHE_SIZE, -1);
73         int[] idTableSubtableSize = env.config.intArrayProperty(Setup.WS_TABLE_SUBTABLE_SIZE, new int[] {-1});
74
75         idTable = new IDTable(env.getDatabaseDir() + "ostab" + File.separator + "tab", idTableBufferSize, idTableCacheSize, idTableSubtableSize);
76         // idTable = new DxHashMap (10000);
77
nameTable = new DxHashMap(100);
78
79         clusterStore = new ClusterStore(env);
80         clusterStore.setMagicStore(this);
81
82         this.garbageCollector = env.getGarbageCollector();
83     }
84
85
86     public synchronized void startup() throws Exception JavaDoc {
87         env.logWriter.newEntry(this, "startup...", LogWriter.INFO);
88         env.logWriter.newEntry(this, "CAUTION: MagicStore is still in early development phase, use with caution!", LogWriter.INFO);
89         clusterStore.startup();
90
91         env.logWriter.newEntry(this, "checking for pending shadow clusters...", LogWriter.INFO);
92
93         boolean isCleanShutdown = isCleanShutdown() && clusterStore.isCleanShutdown();
94
95         boolean isSuccessfullyStarted = false;
96
97         if (isCleanShutdown) {
98             ObjectInputStream nameTableIn = null;
99             ObjectInputStream idTableIn = null;
100             try {
101                 // restore nameTable
102
nameTableIn = new ResolvingObjectInputStream(new FileInputStream(env.getDatabaseDir() + NAME_TABLE_NAME));
103                 int count = nameTableIn.readInt();
104                 for (int i = 0; i < count; i++) {
105                     nameTable.addForKey(nameTableIn.readObject(), nameTableIn.readObject());
106                 }
107                 nameTableIn.close();
108
109                 // restore idTable
110
if (!(idTable instanceof DxDiskHashMap)) {
111                     idTableIn = new ResolvingObjectInputStream(new FileInputStream(env.getDatabaseDir() + ID_TABLE_NAME));
112                     count = idTableIn.readInt();
113                     for (int i = 0; i < count; i++) {
114                         idTable.addForKey(idTableIn.readObject(), idTableIn.readObject());
115                     }
116                     idTableIn.close();
117                 } else {
118                     ((DxDiskHashMap) idTable).re_use();
119                     ((DxDiskHashMap) idTable).setReusable(true);
120                 }
121
122                 isSuccessfullyStarted = true;
123             } catch (FileNotFoundException fe) {
124                 env.logWriter.newEntry(this, " " + fe.toString(), LogWriter.INFO);
125             } catch (Exception JavaDoc e) {
126                 env.logWriter.newEntry(this, " error while starting up... ", LogWriter.INFO);
127                 env.logWriter.newEntry(this, " exception: ", e, LogWriter.DEBUG);
128             } finally {
129                 if (nameTableIn != null) {
130                     nameTableIn.close();
131                 }
132                 if (idTableIn != null) {
133                     idTableIn.close();
134                 }
135             }
136         }
137
138         if (!isCleanShutdown || !isSuccessfullyStarted) {
139             env.logWriter.newEntry(this, " recovering...", LogWriter.INFO);
140             recover();
141         }
142
143         env.logWriter.newEntry(this, " " + idTable.count() + " IDs, " + nameTable.count() + " name(s))",
144                                LogWriter.INFO);
145     }
146
147
148     public synchronized void shutdown() throws Exception JavaDoc {
149         env.logWriter.newEntry(this, "shutdown...", LogWriter.INFO);
150         clusterStore.shutdown();
151
152         commitNameTable();
153
154         commitIDTable();
155         if (idTable instanceof DxDiskHashMap) {
156             ((DxDiskHashMap) idTable).printStatistics();
157             ((DxDiskHashMap) idTable).close();
158         }
159     }
160
161
162     public void save() throws Exception JavaDoc {
163     }
164
165
166     public DxIterator objectIDIterator() {
167         return idTable.iterator();
168     }
169
170
171     protected void commitNameTable() throws IOException {
172         env.logWriter.newEntry(this, "commitNameTable...", LogWriter.DEBUG3);
173
174         String JavaDoc filename = env.getDatabaseDir() + NAME_TABLE_NAME;
175         ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
176         try {
177             out.writeInt(nameTable.count());
178             DxIterator it = nameTable.iterator();
179             while (it.next() != null) {
180                 out.writeObject(it.object());
181                 out.writeObject(it.key());
182             }
183         } catch (Exception JavaDoc e) {
184             new File(filename).delete();
185         } finally {
186             out.close();
187         }
188     }
189
190
191     protected void commitIDTable() throws IOException {
192         env.logWriter.newEntry(this, "commitIDTable...", LogWriter.DEBUG3);
193
194         if (!(idTable instanceof DxDiskHashMap)) {
195             String JavaDoc filename = env.getDatabaseDir() + ID_TABLE_NAME;
196             ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(filename));
197
198             try {
199                 out.writeInt(idTable.count());
200                 DxIterator it = idTable.iterator();
201                 while (it.next() != null) {
202                     out.writeObject(it.object());
203                     out.writeObject(it.key());
204                 }
205             } catch (Exception JavaDoc e) {
206                 new File(filename).delete();
207             } finally {
208                 out.close();
209             }
210         } else {
211             ((IDTable) idTable).setReusable(false);
212             ((IDTable) idTable).writeDirtyTables();
213             ((IDTable) idTable).setReusable(true);
214         }
215     }
216
217
218     /**
219      * Fill idTable and nameTable from the information that are stored in the
220      * clusters directly.
221      *
222      * @throws Exception If a cluster cannot be read.
223      */

224     protected synchronized void recover() throws Exception JavaDoc {
225         env.logWriter.newEntry(this, " cleaning ID table...", LogWriter.INFO);
226         ((DxDiskHashMap) idTable).cleanFiles();
227         (idTable).clear();
228
229         env.logWriter.newEntry(this, " cleaning name table...", LogWriter.INFO);
230         nameTable.clear();
231
232         Set JavaDoc cids = clusterStore.recoverClusterIDs();
233         Set JavaDoc uncommittedTaIDs = clusterStore.uncommittedTaIDs();
234
235         int totalNumClusters = cids.size();
236         int processedNumClusters = 1;
237         for (Iterator JavaDoc it = cids.iterator(); it.hasNext(); ) {
238             ClusterID cid = (ClusterID) it.next();
239
240             Cluster cluster = null;
241             boolean exceptionWhileLoading = false;
242
243             env.logWriter.newEntry(this, " cluster: " + cid + " (" + processedNumClusters++ + " of " + totalNumClusters + ")", LogWriter.INFO);
244             try {
245                 cluster = clusterStore.restoreCluster(cid, uncommittedTaIDs);
246                 env.logWriter.newEntry(this, " " + cluster.containers().count() + " containers", LogWriter.INFO);
247             } catch (Exception JavaDoc e) {
248                 env.logWriter.newEntry(this, "exception while loading cluster: " + cid + " (" + e + ")", LogWriter.WARN);
249                 env.logWriter.newEntry(this, "", e, LogWriter.DEBUG);
250                 exceptionWhileLoading = true;
251             }
252
253             if (exceptionWhileLoading || cluster.containers().isEmpty()) {
254                 if (exceptionWhileLoading) {
255                     env.logWriter.newEntry(this, " unable to read cluster - should be deleted!", LogWriter.INFO);
256                 } else {
257                     env.logWriter.newEntry(this, " cluster is empty - should be deleted!", LogWriter.INFO);
258                 }
259                 if (cluster != null) {
260                     env.logWriter.newEntry(this, " try to delete cluster...", LogWriter.INFO);
261                     cluster.delete();
262                 }
263             } else {
264                 // fill in idTable and nameTable
265
DxIterator it2 = cluster.containers().iterator();
266                 StorageObjectContainer container;
267                 while ((container = (StorageObjectContainer) it2.next()) != null) {
268                     if (env.logWriter.hasTarget(LogWriter.DEBUG)) {
269                         if (container.id().value()==1) {
270                             env.logWriter.newEntry(this, "Adding container "+container+".", LogWriter.DEBUG);
271                         }
272                     }
273                     if (idTable.addForKey(cluster.clusterID(), container.id()) == false) {
274                         throw new IllegalStateException JavaDoc("Unable to add container "+container+" to ID table because cluster ID "+idTable.elementForKey(container.id())+" is already registered for container ID "+container.id()+".");
275                     }
276                     if (container.name() != null) {
277                         env.logWriter.newEntry(this, " adding name: " + container.name(), LogWriter.INFO);
278                         if (nameTable.addForKey(container.id(), container.name()) == false) {
279                             throw new IllegalStateException JavaDoc("Unable to add name to name table: " + container.name());
280                         }
281                     }
282                 }
283             }
284             clusterStore.unloadCluster(cid, false);
285         }
286         commitIDTable();
287         commitNameTable();
288     }
289
290
291     public synchronized ObjectContainer newContainerAndLock(Transaction ta, OzoneCompatible target, ObjectID objID,
292                                                                   Permissions permissions, int lockLevel) throws Exception JavaDoc {
293
294
295         StorageObjectContainer container = new MagicObjectContainer(objID);
296
297         if (target != null) {
298             container.setTarget(target);
299         }
300
301         clusterStore.registerContainerAndLock(container, permissions, ta, lockLevel);
302
303         boolean alright = false;
304
305         try {
306
307             garbageCollector.notifyNewObjectContainer(container);
308
309             MagicTransaction transaction = (MagicTransaction) ta;
310             ClusterID cid = container.getCluster().clusterID();
311             ObjectID oid = container.id();
312
313             if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
314                 env.logWriter.newEntry(this, "newContainer(): cid=" + cid + ",oid=" + oid + ".", LogWriter.DEBUG3);
315             }
316
317             transaction.idTable.addForKey(cid, oid);
318             transaction.idTableChanges_push(new IDTableChange(oid, cid, IDTableChange.STATE_ADDED));
319
320             alright = true;
321
322             return container;
323         } finally {
324             if (!alright) {
325                 container.getCluster().lock().release(ta);
326             }
327         }
328     }
329
330
331     // public synchronized void deleteContainer (Transaction ta, ObjectContainer _container)
332
// throws Exception {
333
// if (env.logWriter.hasTarget (LogWriter.DEBUG3))
334
// env.logWriter.newEntry (this, "deleteContainer()", LogWriter.DEBUG3);
335
//
336
// MagicObjectContainer container = (MagicObjectContainer)_container;
337
// taData.idTableChanges.push (new IDTableChange (oid, cid, IDTableChange.STATE_ADDED));
338

339
340     public void updateLockLevel(Transaction _ta, ObjectContainer _container) throws IOException {
341         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
342             env.logWriter.newEntry(this, "updateLockLevel()", LogWriter.DEBUG3);
343         }
344
345         if (_container instanceof StorageObjectContainer) {
346             StorageObjectContainer container = (StorageObjectContainer) _container;
347             container.getCluster().updateLockLevel(_ta);
348
349             MagicTransaction wizardTa = (MagicTransaction) _ta;
350             wizardTa.idTable.addForKey(container.getCluster().clusterID(), container.id());
351         }
352     }
353
354
355     /**
356      * Returns the ObjectContainer for the given ObjectID or null if there is
357      * no such container.<p>
358      *
359      * @param ta the Transaction for within the container is requested or null.
360      *
361      * Impl. Note: For performance reasons this is the only method of this Store
362      * that is not synchronized. This will not cause problems because the only
363      * field that is updated inside the method (currentContainer) does not need
364      * to be stable while this method is running.
365      */

366     public ObjectContainer containerForID(Transaction ta, ObjectID id) throws ObjectNotFoundException, IOException, ClassNotFoundException JavaDoc {
367
368         StorageObjectContainer container = null;
369         MagicTransaction magicTa = (MagicTransaction) ta;
370         MagicTransaction transaction = (MagicTransaction) ta;
371
372         // search the LRU cluster to speed things up; since this is not
373
// synchronized, checking and accessing currentCluster must be done in
374
// one line to avoid other thread to change the variable in between
375
// container = (currentCluster != null && currentCluster.lock != null) ? currentCluster.containerForID (id) : null;
376
// if (container != null) {
377
// // System.out.print ("+");
378
// return container.isDeleted() ? null : container;
379
// }
380

381         ClusterID cid = null;
382
383         // search members of current ta first
384
if (ta != null) {
385             DxMap taDataIDTable = transaction.idTable;
386             cid = (ClusterID) taDataIDTable.elementForKey(id);
387
388             if (cid == null && transaction.lrucid != null) {
389                 Cluster lru = clusterStore.loadCluster(transaction.lrucid, magicTa);
390
391                 if (lru != null) {
392                     container = lru.lock() != null ? lru.containerForID(id) : null;
393                     if (container != null) {
394                         // System.out.print ("+");
395
if (container.isDeleted()) {
396                             return null;
397                         } else {
398                             return container;
399                         }
400                     }
401                 }
402             }
403         }
404
405         // search global table ONLY if ta doesn't contain the container
406
if (cid == null) {
407             cid = (ClusterID) idTable.elementForKey(id);
408         }
409
410
411         if (cid == null) {
412             return null;
413         } else {
414             // System.out.println ("-");
415
Cluster cluster = clusterStore.loadCluster(cid, magicTa);
416
417             if (cluster == null) {
418                 throw new ObjectNotFoundException("No object registered for ID: " + id);
419             }
420
421             if (transaction != null) {
422                 transaction.lrucid = cid;
423             }
424
425             try {
426                 container = cluster.containerForID(id);
427
428                 if (container.isDeleted()) {
429                     return null;
430                 } else {
431                     return container;
432                 }
433             } catch (NullPointerException JavaDoc e) {
434                 env.logWriter.newEntry(this, "NullPointerException during " + cluster + ".containerForID(" + id + "). We were able to load a cluster for that ID but the cluster did not contain the container. This is an inconsistent view.", e, LogWriter.ERROR);
435                 throw e;
436             }
437
438         }
439     }
440
441     public DxSet objectNames(Transaction ta) {
442         env.logWriter.newEntry(this, "Returning objectnames", LogWriter.DEBUG);
443
444         return nameTable.keySet();
445     }
446
447     public synchronized ObjectContainer containerForName(Transaction ta, String JavaDoc name) throws Exception JavaDoc {
448         if (name == null) {
449             return null;
450         }
451
452         MagicTransaction wizardTa = (MagicTransaction) ta;
453
454         if (ta == null || wizardTa.nameTable == null) {
455             ObjectID oid = (ObjectID) nameTable.elementForKey(name);
456             return oid != null ? containerForID(ta, oid) : null;
457         }
458
459         if (ta != null) {
460             ObjectID oid = (ObjectID) wizardTa.nameTable.elementForKey(name);
461             return oid != null ? containerForID(ta, oid) : null;
462         }
463         return null;
464     }
465
466
467     public synchronized void nameContainer(Transaction ta, ObjectContainer container, String JavaDoc name)
468             throws PermissionDeniedException {
469
470         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
471             env.logWriter.newEntry(this, "nameContainer(), nameTable=" + nameTable + ".", LogWriter.DEBUG3);
472         }
473
474         MagicTransaction transaction = (MagicTransaction) ta;
475         if (transaction.nameTable == null) {
476             Object JavaDoc o = null;
477             try {
478                 java.lang.reflect.Method JavaDoc method = nameTable.getClass().getDeclaredMethod("clone", null);
479                 if (env.logWriter.hasTarget(LogWriter.DEBUG)) {
480                     env.logWriter.newEntry(this, "nameContainer(), nameTable=" + nameTable + ", nameTable.getClass().getDeclaredMethod(\"clone\",null)=" + method + ".", LogWriter.DEBUG);
481                 }
482                 o = method.invoke(nameTable, null);
483             } catch (Exception JavaDoc e) {
484                 env.logWriter.newEntry(this, "nameContainer(): caught: ", e, LogWriter.INFO);
485             }
486
487             if (o == null) {
488                 o = nameTable.clone();
489             }
490
491
492             transaction.nameTable = (DxMap) o;
493         }
494
495         String JavaDoc oldName = container.name();
496         if (oldName != null) {
497             transaction.nameTable.removeForKey(oldName);
498             transaction.nameTableChanges_push(new NameTableChange(container.id(), oldName,
499                                                              NameTableChange.STATE_REMOVED));
500         }
501
502         container.nameTarget(name);
503
504         if (name != null) {
505             if (oldName == null) {
506                 garbageCollector.notifyNewObjectName(container);
507             }
508             transaction.nameTable.addForKey(container.id(), name);
509             transaction.nameTableChanges_push(new NameTableChange(container.id(), name, NameTableChange.STATE_ADDED));
510         }
511     }
512
513
514     public synchronized DxBag clusterOfID(ObjectID id) throws Exception JavaDoc {
515         throw new RuntimeException JavaDoc("this method is implementation specific and should be removed from StoreManager");
516     }
517
518
519     public synchronized void prepareCommitTransaction(Transaction ta) throws IOException, ClassNotFoundException JavaDoc {
520         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
521             env.logWriter.newEntry(this, "prepareCommitTransaction()", LogWriter.DEBUG3);
522         }
523
524         MagicTransaction transaction = (MagicTransaction) ta;
525
526         // initialize transaction data fields
527
transaction.commitClusterIDs = new DxHashSet(64);
528
529         DxIterator it = transaction.idTable.iterator();
530 // env.logWriter.newEntry( this, "idTable count: " + taData.idTable.count(), LogWriter.DEBUG2 );
531
ClusterID cid;
532
533         while ((cid = (ClusterID) it.next()) != null) {
534             if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
535                 env.logWriter.newEntry(this, "checking cluster: " + cid + " ...", LogWriter.DEBUG3);
536             }
537
538             if (!transaction.commitClusterIDs.contains(cid)) {
539 // env.logWriter.newEntry( this, "prepare commit cluster: " + cid, LogWriter.DEBUG2 );
540
transaction.commitClusterIDs.add(cid);
541
542                 Cluster cluster = clusterStore.loadCluster(cid, transaction);
543
544                 // we don't need to do all the stuff if there is no WRITE
545
// lock
546
if (cluster.lock().level(ta) >= Lock.LEVEL_WRITE) {
547
548                     // delete containers from cluster and
549
// prepare newID and deletedID tables
550
DxIterator it2 = cluster.containers().iterator();
551                     StorageObjectContainer container;
552                     while ((container = (StorageObjectContainer) it2.next()) != null) {
553
554                         if (container.isDeleted()) {
555                             if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
556                                 env.logWriter.newEntry(this, "container deleted: " + container.id(), LogWriter.DEBUG3);
557                             }
558
559                             clusterStore.invalidateContainer(container);
560                             transaction.idTableChanges_push(new IDTableChange(container.id(), cid, IDTableChange.STATE_REMOVED));
561
562                             if (container.name() != null) {
563                                 transaction.nameTableChanges_push(new NameTableChange(container.id(), container.name(), NameTableChange.STATE_REMOVED));
564                             }
565                         }
566                         container.clearState();
567                     }
568                 }
569                 clusterStore.prepareCommitCluster(ta, cid);
570             }
571         }
572     }
573
574
575     protected boolean isCleanShutdown() {
576         return !(new File(COMMIT_FLAG_NAME).exists());
577     }
578
579
580     protected void beginCommit(Transaction ta) throws IOException {
581 // env.logWriter.newEntry( this, "beginCommit...", LogWriter.DEBUG2 );
582

583         // do nothing if this was just a read transaction
584
if (ta.maxLockLevel() < Lock.LEVEL_WRITE) {
585             return;
586         }
587
588         int commitCount = 0;
589
590         // read the current commitCount from file
591
File f = new File(env.getDatabaseDir() + COMMIT_FLAG_NAME);
592         if (f.exists()) {
593             DataInputStream in = null;
594             try {
595                 in = new DataInputStream(new FileInputStream(f));
596                 commitCount = in.readInt();
597             } finally {
598                 if (in != null) {
599                     in.close();
600                 }
601             }
602         }
603         commitCount++;
604
605         DataOutputStream out = null;
606         try {
607             out = new DataOutputStream(new FileOutputStream(f));
608             out.writeInt(commitCount);
609         } finally {
610             if (out != null) {
611                 out.close();
612             }
613         }
614     }
615
616
617     protected void endCommit(Transaction ta) throws IOException {
618 // env.logWriter.newEntry( this, "endCommit...", LogWriter.DEBUG2 );
619

620         // do nothing if this was just a read transaction
621
if (ta.maxLockLevel() < Lock.LEVEL_WRITE) {
622             return;
623         }
624
625         int commitCount = 0;
626
627         // read the current commitCount from file
628
File f = new File(env.getDatabaseDir() + COMMIT_FLAG_NAME);
629         if (f.exists()) {
630             DataInputStream in = null;
631             try {
632                 in = new DataInputStream(new FileInputStream(f));
633                 commitCount = in.readInt();
634             } finally {
635                 if (in != null) {
636                     in.close();
637                 }
638             }
639         } else {
640             throw new RuntimeException JavaDoc("No commit flag file present.");
641         }
642         commitCount--;
643
644         if (commitCount > 0) {
645             DataOutputStream out = null;
646             try {
647                 out = new DataOutputStream(new FileOutputStream(f));
648                 out.writeInt(commitCount);
649             } finally {
650                 if (out != null) {
651                     out.close();
652                 }
653             }
654         } else {
655             if (!(f.delete())) {
656                 throw new RuntimeException JavaDoc("Unable to delete commit flag file. ");
657             }
658         }
659     }
660
661
662     public synchronized void commitTransaction(Transaction ta) throws IOException, ClassNotFoundException JavaDoc {
663         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
664             env.logWriter.newEntry(this, "commitTransaction()", LogWriter.DEBUG3);
665         }
666
667         beginCommit(ta);
668
669         MagicTransaction transaction = (MagicTransaction) ta;
670
671         // actually write changed clusters to disk
672
DxSet commitClusterIDs = transaction.commitClusterIDs;
673         DxIterator it = commitClusterIDs.iterator();
674
675         ClusterID cid;
676         while ((cid = (ClusterID) it.next()) != null) {
677             if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {
678                 env.logWriter.newEntry(this, "commit cluster: " + cid, LogWriter.DEBUG2);
679             }
680             clusterStore.commitCluster(ta, cid);
681         }
682
683         // update global idTable
684
boolean isIDTableChanged = false;
685         IDTableChange idChange = null;
686
687         while ((idChange = transaction.idTableChanges_pop()) != null) {
688             isIDTableChanged = true;
689
690             switch (idChange.state) {
691                 case IDTableChange.STATE_ADDED:
692                     {
693 // env.logWriter.newEntry( this, "commit added oid: " + idChange.oid, LogWriter.DEBUG2 );
694
if (idTable.addForKey(idChange.cid, idChange.oid) == false) {
695                             throw new IllegalStateException JavaDoc("Unable to add OID to global ID table.");
696                         }
697                         break;
698                     }
699                 case IDTableChange.STATE_REMOVED:
700                     {
701                         if (false) {
702                             env.logWriter.newEntry(this, "commit removed oid: " + idChange.oid, LogWriter.DEBUG2);
703                         }
704
705                         if (idTable.removeForKey(idChange.oid) == null) {
706                             throw new IllegalStateException JavaDoc("Unable to remove OID from global ID table.");
707                         }
708                         break;
709                     }
710                 default:
711                     {
712                         throw new RuntimeException JavaDoc("ID change table entry has inproper state.");
713                     }
714             }
715         }
716
717         // write changes to disk
718
if (isIDTableChanged) {
719             commitIDTable();
720         }
721
722         // update global nameTable
723
boolean isNameTableChanged = false;
724         NameTableChange nameChange = transaction.nameTableChanges_pop();
725
726         while (nameChange != null) {
727             isNameTableChanged = true;
728
729             switch (nameChange.state) {
730                 case NameTableChange.STATE_ADDED:
731                     {
732                         nameTable.addForKey(nameChange.oid, nameChange.name);
733                         break;
734                     }
735                 case NameTableChange.STATE_REMOVED:
736                     {
737                         nameTable.removeForKey(nameChange.name);
738                         break;
739                     }
740                 default:
741                     {
742                         throw new RuntimeException JavaDoc("Name change table entry has inproper state.");
743                     }
744             }
745             nameChange = transaction.nameTableChanges_pop();
746         }
747
748         // write changes to disk
749
if (isNameTableChanged) {
750             commitNameTable();
751         }
752
753         endCommit(ta);
754
755         if (env.logWriter.hasTarget(LogWriter.DEBUG2)) {
756             env.logWriter.newEntry(this, " idTable.count(): " + idTable.count(), LogWriter.DEBUG2);
757             env.logWriter.newEntry(this, " nameTable.count(): " + nameTable.count(), LogWriter.DEBUG2);
758         }
759     }
760
761
762     /**
763      * @param ta ID of the comitting transaction.
764      */

765     public synchronized void abortTransaction(Transaction ta) throws IOException, ClassNotFoundException JavaDoc {
766         if (env.logWriter.hasTarget(LogWriter.DEBUG3)) {
767             env.logWriter.newEntry(this, "abortTransaction()", LogWriter.DEBUG3);
768         }
769
770         clusterStore.abortTransaction((MagicTransaction) ta);
771     }
772
773     /**
774      Tells this StoreManager to report every named object to the garbage collector.
775      */

776     public void reportNamedObjectsToGarbageCollector() {
777         synchronized (this) {
778             DxIterator i = nameTable.elementSet().iterator();
779
780             while (i.next() != null) {
781                 garbageCollector.notifyNamedObject((ObjectID) i.object());
782             }
783         }
784     }
785
786     public Transaction createTransaction(Env env, User user) {
787         return new MagicTransaction(env, user);
788     }
789
790 }
791
Popular Tags