001: /**
002: * JDBM LICENSE v1.00
003: *
004: * Redistribution and use of this software and associated documentation
005: * ("Software"), with or without modification, are permitted provided
006: * that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain copyright
009: * statements and notices. Redistributions must also contain a
010: * copy of this document.
011: *
012: * 2. Redistributions in binary form must reproduce the
013: * above copyright notice, this list of conditions and the
014: * following disclaimer in the documentation and/or other
015: * materials provided with the distribution.
016: *
017: * 3. The name "JDBM" must not be used to endorse or promote
018: * products derived from this Software without prior written
019: * permission of Cees de Groot. For written permission,
020: * please contact cg@cdegroot.com.
021: *
022: * 4. Products derived from this Software may not be called "JDBM"
023: * nor may "JDBM" appear in their names without prior written
024: * permission of Cees de Groot.
025: *
026: * 5. Due credit should be given to the JDBM Project
027: * (http://jdbm.sourceforge.net/).
028: *
029: * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
030: * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
031: * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
032: * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
033: * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
034: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
035: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
036: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
037: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
038: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
039: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
040: * OF THE POSSIBILITY OF SUCH DAMAGE.
041: *
042: * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
043: * Contributions are Copyright (C) 2000 by their associated contributors.
044: *
045: * $Id: FileHeader.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
046: */package jdbm.recman;
047:
048: /**
049: * This class represents a file header. It is a 1:1 representation of
050: * the data that appears in block 0 of a file.
051: */
052: class FileHeader implements BlockView {
053: // offsets
054: private static final short O_MAGIC = 0; // short magic
055: private static final short O_LISTS = Magic.SZ_SHORT; // long[2*NLISTS]
056: private static final int O_ROOTS = O_LISTS
057: + (Magic.NLISTS * 2 * Magic.SZ_LONG);
058:
059: // my block
060: private BlockIo block;
061:
062: /** The number of "root" rowids available in the file. */
063: static final int NROOTS = (RecordFile.BLOCK_SIZE - O_ROOTS)
064: / Magic.SZ_LONG;
065:
066: /**
067: * Constructs a FileHeader object from a block.
068: *
069: * @param block The block that contains the file header
070: * @param isNew If true, the file header is for a new file.
071: * @throws IOException if the block is too short to keep the file
072: * header.
073: */
074: FileHeader(BlockIo block, boolean isNew) {
075: this .block = block;
076: if (isNew)
077: block.writeShort(O_MAGIC, Magic.FILE_HEADER);
078: else if (!magicOk())
079: throw new Error("CRITICAL: file header magic not OK "
080: + block.readShort(O_MAGIC));
081: }
082:
083: /** Returns true if the magic corresponds with the fileHeader magic. */
084: private boolean magicOk() {
085: return block.readShort(O_MAGIC) == Magic.FILE_HEADER;
086: }
087:
088: /** Returns the offset of the "first" block of the indicated list */
089: private short offsetOfFirst(int list) {
090: return (short) (O_LISTS + (2 * Magic.SZ_LONG * list));
091: }
092:
093: /** Returns the offset of the "last" block of the indicated list */
094: private short offsetOfLast(int list) {
095: return (short) (offsetOfFirst(list) + Magic.SZ_LONG);
096: }
097:
098: /** Returns the offset of the indicated root */
099: private short offsetOfRoot(int root) {
100: return (short) (O_ROOTS + (root * Magic.SZ_LONG));
101: }
102:
103: /**
104: * Returns the first block of the indicated list
105: */
106: long getFirstOf(int list) {
107: return block.readLong(offsetOfFirst(list));
108: }
109:
110: /**
111: * Sets the first block of the indicated list
112: */
113: void setFirstOf(int list, long value) {
114: block.writeLong(offsetOfFirst(list), value);
115: }
116:
117: /**
118: * Returns the last block of the indicated list
119: */
120: long getLastOf(int list) {
121: return block.readLong(offsetOfLast(list));
122: }
123:
124: /**
125: * Sets the last block of the indicated list
126: */
127: void setLastOf(int list, long value) {
128: block.writeLong(offsetOfLast(list), value);
129: }
130:
131: /**
132: * Returns the indicated root rowid. A root rowid is a special rowid
133: * that needs to be kept between sessions. It could conceivably be
134: * stored in a special file, but as a large amount of space in the
135: * block header is wasted anyway, it's more useful to store it where
136: * it belongs.
137: *
138: * @see #NROOTS
139: */
140: long getRoot(int root) {
141: return block.readLong(offsetOfRoot(root));
142: }
143:
144: /**
145: * Sets the indicated root rowid.
146: *
147: * @see #getRoot
148: * @see #NROOTS
149: */
150: void setRoot(int root, long rowid) {
151: block.writeLong(offsetOfRoot(root), rowid);
152: }
153: }
|