001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.fileheader;
022:
023: import com.db4o.Db4oIOException;
024: import com.db4o.internal.*;
025:
026: /**
027: * @exclude
028: */
029: public class FileHeader1 extends FileHeader {
030:
031: // The header format is:
032:
033: // (byte) 'd'
034: // (byte) 'b'
035: // (byte) '4'
036: // (byte) 'o'
037: // (byte) headerVersion
038: // (int) headerLock
039: // (long) openTime
040: // (long) accessTime
041: // (int) Transaction pointer 1
042: // (int) Transaction pointer 2
043: // (int) blockSize
044: // (int) classCollectionID
045: // (int) freespaceID
046: // (int) variablePartID
047:
048: private static final byte[] SIGNATURE = { (byte) 'd', (byte) 'b',
049: (byte) '4', (byte) 'o' };
050:
051: private static byte VERSION = 1;
052:
053: private static final int HEADER_LOCK_OFFSET = SIGNATURE.length + 1;
054: private static final int OPEN_TIME_OFFSET = HEADER_LOCK_OFFSET
055: + Const4.INT_LENGTH;
056: private static final int ACCESS_TIME_OFFSET = OPEN_TIME_OFFSET
057: + Const4.LONG_LENGTH;
058: private static final int TRANSACTION_POINTER_OFFSET = ACCESS_TIME_OFFSET
059: + Const4.LONG_LENGTH;
060:
061: public static final int LENGTH = TRANSACTION_POINTER_OFFSET
062: + (Const4.INT_LENGTH * 6);
063:
064: private TimerFileLock _timerFileLock;
065:
066: private Transaction _interruptedTransaction;
067:
068: private FileHeaderVariablePart1 _variablePart;
069:
070: public void close() throws Db4oIOException {
071: _timerFileLock.close();
072: }
073:
074: public void initNew(LocalObjectContainer file)
075: throws Db4oIOException {
076: commonTasksForNewAndRead(file);
077: _variablePart = new FileHeaderVariablePart1(0, file
078: .systemData());
079: writeVariablePart(file, 0);
080: }
081:
082: protected FileHeader newOnSignatureMatch(LocalObjectContainer file,
083: Buffer reader) {
084: if (signatureMatches(reader, SIGNATURE, VERSION)) {
085: return new FileHeader1();
086: }
087: return null;
088: }
089:
090: private void newTimerFileLock(LocalObjectContainer file) {
091: _timerFileLock = TimerFileLock.forFile(file);
092: _timerFileLock.setAddresses(0, OPEN_TIME_OFFSET,
093: ACCESS_TIME_OFFSET);
094: }
095:
096: public Transaction interruptedTransaction() {
097: return _interruptedTransaction;
098: }
099:
100: public int length() {
101: return LENGTH;
102: }
103:
104: protected void readFixedPart(LocalObjectContainer file,
105: Buffer reader) {
106: commonTasksForNewAndRead(file);
107: checkThreadFileLock(file, reader);
108: reader.seek(TRANSACTION_POINTER_OFFSET);
109: _interruptedTransaction = LocalTransaction
110: .readInterruptedTransaction(file, reader);
111: file.blockSizeReadFromFile(reader.readInt());
112: readClassCollectionAndFreeSpace(file, reader);
113: _variablePart = new FileHeaderVariablePart1(reader.readInt(),
114: file.systemData());
115: }
116:
117: private void checkThreadFileLock(LocalObjectContainer container,
118: Buffer reader) {
119: reader.seek(ACCESS_TIME_OFFSET);
120: long lastAccessTime = reader.readLong();
121: if (FileHeader.lockedByOtherSession(container, lastAccessTime)) {
122: _timerFileLock.checkIfOtherSessionAlive(container, 0,
123: ACCESS_TIME_OFFSET, lastAccessTime);
124: }
125: }
126:
127: private void commonTasksForNewAndRead(LocalObjectContainer file) {
128: newTimerFileLock(file);
129: file._handlers.oldEncryptionOff();
130: }
131:
132: public void readVariablePart(LocalObjectContainer file) {
133: _variablePart.read(file.systemTransaction());
134: }
135:
136: public void writeFixedPart(LocalObjectContainer file,
137: boolean startFileLockingThread, boolean shuttingDown,
138: StatefulBuffer writer, int blockSize, int freespaceID) {
139: writer.append(SIGNATURE);
140: writer.writeByte(VERSION);
141: writer.writeInt((int) timeToWrite(_timerFileLock.openTime(),
142: shuttingDown));
143: writer.writeLong(timeToWrite(_timerFileLock.openTime(),
144: shuttingDown));
145: writer.writeLong(timeToWrite(System.currentTimeMillis(),
146: shuttingDown));
147: writer.writeInt(0); // transaction pointer 1 for "in-commit-mode"
148: writer.writeInt(0); // transaction pointer 2
149: writer.writeInt(blockSize);
150: writer.writeInt(file.systemData().classCollectionID());
151: writer.writeInt(freespaceID);
152: writer.writeInt(_variablePart.getID());
153: writer.noXByteCheck();
154: writer.write();
155: file.syncFiles();
156: if (startFileLockingThread) {
157: _timerFileLock.start();
158: }
159: }
160:
161: public void writeTransactionPointer(Transaction systemTransaction,
162: int transactionAddress) {
163: writeTransactionPointer(systemTransaction, transactionAddress,
164: 0, TRANSACTION_POINTER_OFFSET);
165: }
166:
167: public void writeVariablePart(LocalObjectContainer file, int part) {
168: _variablePart.setStateDirty();
169: _variablePart.write(file.systemTransaction());
170: }
171:
172: }
|