View Javadoc

1   /*
2    * Copyright 2004 Charles Blaxland
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package mnemosyne.archiver;
17  
18  import mnemosyne.core.*;
19  import org.apache.commons.logging.Log;
20  import org.apache.commons.logging.LogFactory;
21  
22  /***
23   * @version $Id: FileSystemArchiver.java,v 1.1.1.1 2004/08/07 06:40:53 charlesblaxland Exp $
24   */
25  public class FileSystemArchiver implements Archiver
26  {
27      private static final Log log = LogFactory.getLog(FileSystemArchiver.class);
28  
29      private SnapshotDirectory snapshotDirectory;
30      private TransactionDirectory transactionDirectory;
31      private ArchiveSequence sequence = new ArchiveSequence();
32      private VersionManager versionMgr;
33      private PersistentObjectFactory persistentObjectFactory;
34  
35      public FileSystemArchiver(VersionManager versionMgr, PersistentObjectFactory persistentObjectFactory, String directory)
36      {
37          this.snapshotDirectory = new SnapshotDirectory(directory, sequence);
38          this.transactionDirectory = new TransactionDirectory(directory, sequence);
39          this.versionMgr = versionMgr;
40          this.persistentObjectFactory = persistentObjectFactory;
41      }
42  
43      public PersistentRoot loadLatest() throws ArchiverException
44      {
45          log.info("Reloading persistent graph");
46          PersistentRoot root = null;
47          if (!snapshotDirectory.isEmpty())
48          {
49              long latestSnapshotNumber = snapshotDirectory.getLatestSnapshotSequenceNumber();
50              AggregatedTransaction aggregatedTransaction = new AggregatedTransaction();
51              ArchiveContext context = ArchiveContext.get();
52              context.setAggregatedTransaction(aggregatedTransaction);
53              context.setPersistentObjectFactory(persistentObjectFactory);
54              transactionDirectory.readTransactionsSinceSnapshot(latestSnapshotNumber);
55              aggregatedTransaction.setComplete(true);
56              root = snapshotDirectory.readLatestSnapshot();
57          }
58  
59          if (root == null)
60          {
61              log.info("Creating new persistent root");
62              root = new PersistentRootImpl();
63              PersistentObject persistentObject = persistentObjectFactory.createPersistentObject();
64              persistentObject.initialize(root);
65              ((Persistable) root).setPersistentObject(persistentObject);
66              saveSnapshot(root);
67          }
68  
69          log.info("Persistent graph reloaded successfully");
70          return root;
71      }
72  
73      public void saveSnapshot(PersistentRoot root) throws ArchiverException
74      {
75          // TODO - Fix syncronization issue with snapshots.
76          // This issue arises when the following sequence of events occurs
77          //   1. saveSnapshot called by thread 1
78          //   2. Thread 1 advanced to latest version (say, "10").
79          //   3. Thread 2 writes a transaction (a new seq number is allocated for it, say "00060")
80          //   4. Thread 2 commits the pgraph (new version = "11")
81          //   5. Snapshot sequence number allocated by thread 1, "00061", and snapshot written
82          //   In this scenario, we have written the pgraph at version "10" to 00061, but version "11" has been
83          //   written to "00060".  Obviously this will result in an incorrect graph when reread.
84          log.info("Saving snapshot...");
85          versionMgr.advanceThisThreadsVersion();
86          snapshotDirectory.writeArchiveFile(root);
87          log.info("Snapshot complete");
88      }
89  
90      public void saveTransaction(Transaction transaction) throws ArchiverException
91      {
92          log.info("Saving transaction...");
93          transactionDirectory.writeArchiveFile(transaction);
94          log.info("Transaction saved");
95      }
96  }