/******************************************************************************* * Copyright 2010 Cees De Groot, Alex Boisvert, Jan Kotek * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package de.mxro.thrd.jdbm2V22.recman; import java.io.IOException; /** * This class represents a page header. It is the common superclass for * all different page views. */ class PageHeader implements BlockView { // offsets private static final short O_MAGIC = 0; // short magic private static final short O_NEXT = Magic.SZ_SHORT; // long next private static final short O_PREV = O_NEXT + Magic.SZ_LONG; // long prev protected static final short SIZE = O_PREV + Magic.SZ_LONG; static final short PhysicalRowId_O_BLOCK = 0; // long block static final short PhysicalRowId_O_OFFSET = Magic.SZ_SIX_BYTE_LONG; // short offset static final int PhysicalRowId_SIZE = PhysicalRowId_O_OFFSET + Magic.SZ_SHORT; // my block protected BlockIo block; /** * Constructs a PageHeader object from a block * * @param block The block that contains the file header * @throws IOException if the block is too short to keep the file * header. */ protected PageHeader(BlockIo block) { initialize(block); if (!magicOk()) throw new Error("CRITICAL: page header magic for block " + block.getBlockId() + " not OK " + getMagic()); } /** * Constructs a new PageHeader of the indicated type. Used for newly * created pages. */ PageHeader(BlockIo block, short type) { initialize(block); setType(type); } /** * Factory method to create or return a page header for the * indicated block. */ static PageHeader getView(BlockIo block) { BlockView view = block.getView(); if (view != null && view instanceof PageHeader) return (PageHeader) view; else return new PageHeader(block); } protected void initialize(BlockIo block) { this.block = block; block.setView(this); } /** * Returns true if the magic corresponds with the fileHeader magic. */ private boolean magicOk() { int magic = getMagic(); return magic >= Magic.BLOCK && magic <= (Magic.BLOCK + Magic.FREEPHYSIDS_PAGE); } /** * For paranoia mode */ protected void paranoiaMagicOk() { if (!magicOk()) throw new Error("CRITICAL: page header magic not OK " + getMagic()); } /** Returns the magic code */ short getMagic() { return block.readShort(O_MAGIC); } /** Returns the next block. */ long getNext() { paranoiaMagicOk(); return block.readLong(O_NEXT); } /** Sets the next block. */ void setNext(long next) { paranoiaMagicOk(); block.writeLong(O_NEXT, next); } /** Returns the previous block. */ long getPrev() { paranoiaMagicOk(); return block.readLong(O_PREV); } /** Sets the previous block. */ void setPrev(long prev) { paranoiaMagicOk(); block.writeLong(O_PREV, prev); } /** Sets the type of the page header */ void setType(short type) { block.writeShort(O_MAGIC, (short) (Magic.BLOCK + type)); } /** Returns the block number */ long getLocationBlock(short pos) { return block.readSixByteLong(pos + PhysicalRowId_O_BLOCK); } /** Sets the block number */ void setLocationBlock(short pos,long value) { block.writeSixByteLong(pos + PhysicalRowId_O_BLOCK, value); } /** Returns the offset */ short getLocationOffset(short pos) { return block.readShort(pos + PhysicalRowId_O_OFFSET); } /** Sets the offset */ void setLocationOffset(short pos,short value) { block.writeShort(pos + PhysicalRowId_O_OFFSET, value); } }