1 /**
2 * JDBM LICENSE v1.00
3 *
4 * Redistribution and use of this software and associated documentation
5 * ("Software"), with or without modification, are permitted provided
6 * that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain copyright
9 * statements and notices. Redistributions must also contain a
10 * copy of this document.
11 *
12 * 2. Redistributions in binary form must reproduce the
13 * above copyright notice, this list of conditions and the
14 * following disclaimer in the documentation and/or other
15 * materials provided with the distribution.
16 *
17 * 3. The name "JDBM" must not be used to endorse or promote
18 * products derived from this Software without prior written
19 * permission of Cees de Groot. For written permission,
20 * please contact cg@cdegroot.com.
21 *
22 * 4. Products derived from this Software may not be called "JDBM"
23 * nor may "JDBM" appear in their names without prior written
24 * permission of Cees de Groot.
25 *
26 * 5. Due credit should be given to the JDBM Project
27 * (http://jdbm.sourceforge.net/).
28 *
29 * THIS SOFTWARE IS PROVIDED BY THE JDBM PROJECT AND CONTRIBUTORS
30 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
31 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
32 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
33 * CEES DE GROOT OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
34 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
36 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
37 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
38 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
39 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
40 * OF THE POSSIBILITY OF SUCH DAMAGE.
41 *
42 * Copyright 2000 (C) Cees de Groot. All Rights Reserved.
43 * Contributions are Copyright (C) 2000 by their associated contributors.
44 *
45 * $Id: FileHeader.java,v 1.3 2005/06/25 23:12:32 doomdark Exp $
46 */
47
48 package jdbm.recman;
49
50 /**
51 * This class represents a file header. It is a 1:1 representation of
52 * the data that appears in block 0 of a file.
53 */
54 class FileHeader implements BlockView {
55 // offsets
56 private static final short O_MAGIC = 0; // short magic
57 private static final short O_LISTS = Magic.SZ_SHORT; // long[2*NLISTS]
58 private static final int O_ROOTS =
59 O_LISTS + (Magic.NLISTS * 2 * Magic.SZ_LONG);
60
61 // my block
62 private BlockIo block;
63
64 /** The number of "root" rowids available in the file. */
65 static final int NROOTS =
66 (RecordFile.BLOCK_SIZE - O_ROOTS) / Magic.SZ_LONG;
67
68 /**
69 * Constructs a FileHeader object from a block.
70 *
71 * @param block The block that contains the file header
72 * @param isNew If true, the file header is for a new file.
73 * @throws IOException if the block is too short to keep the file
74 * header.
75 */
76 FileHeader(BlockIo block, boolean isNew) {
77 this.block = block;
78 if (isNew)
79 block.writeShort(O_MAGIC, Magic.FILE_HEADER);
80 else if (!magicOk())
81 throw new Error("CRITICAL: file header magic not OK "
82 + block.readShort(O_MAGIC));
83 }
84
85 /** Returns true if the magic corresponds with the fileHeader magic. */
86 private boolean magicOk() {
87 return block.readShort(O_MAGIC) == Magic.FILE_HEADER;
88 }
89
90
91 /** Returns the offset of the "first" block of the indicated list */
92 private short offsetOfFirst(int list) {
93 return (short) (O_LISTS + (2 * Magic.SZ_LONG * list));
94 }
95
96 /** Returns the offset of the "last" block of the indicated list */
97 private short offsetOfLast(int list) {
98 return (short) (offsetOfFirst(list) + Magic.SZ_LONG);
99 }
100
101 /** Returns the offset of the indicated root */
102 private short offsetOfRoot(int root) {
103 return (short) (O_ROOTS + (root * Magic.SZ_LONG));
104 }
105
106 /**
107 * Returns the first block of the indicated list
108 */
109 long getFirstOf(int list) {
110 return block.readLong(offsetOfFirst(list));
111 }
112
113 /**
114 * Sets the first block of the indicated list
115 */
116 void setFirstOf(int list, long value) {
117 block.writeLong(offsetOfFirst(list), value);
118 }
119
120 /**
121 * Returns the last block of the indicated list
122 */
123 long getLastOf(int list) {
124 return block.readLong(offsetOfLast(list));
125 }
126
127 /**
128 * Sets the last block of the indicated list
129 */
130 void setLastOf(int list, long value) {
131 block.writeLong(offsetOfLast(list), value);
132 }
133
134 /**
135 * Returns the indicated root rowid. A root rowid is a special rowid
136 * that needs to be kept between sessions. It could conceivably be
137 * stored in a special file, but as a large amount of space in the
138 * block header is wasted anyway, it's more useful to store it where
139 * it belongs.
140 *
141 * @see #NROOTS
142 */
143 long getRoot(int root) {
144 return block.readLong(offsetOfRoot(root));
145 }
146
147 /**
148 * Sets the indicated root rowid.
149 *
150 * @see #getRoot
151 * @see #NROOTS
152 */
153 void setRoot(int root, long rowid) {
154 block.writeLong(offsetOfRoot(root), rowid);
155 }
156 }