|
What this is
Other links
The source code/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2001 Sun * Microsystems, Inc. All Rights Reserved. */ package org.netbeans.mdr.persistence.btreeimpl.btreestorage; import java.io.*; import java.text.*; import org.netbeans.mdr.persistence.*; /** A map page, used by the log file to keep track of before-image pages */ class MapPage { /* page size */ private int pageSize; /* offset in the file of this page */ private int myOffset; /* number of files being logged */ private short numFiles; /* maximum page entries that fit */ private short maxPages; /* file header data for these files */ private long fileId; private long timeStamp; private long newTimeStamp; /* number of before-image pages mapped by this page */ private short pageCount; /* checksum for this page */ private short checksum; private static final int FIXED_SIZE = 40; /* size of above */ /** end-of-file marks for each loggged file */ private int oldEOF[]; /** offsets for each page described by this map */ private int offsets[]; /** Create a new map mage * @param pgSz the page size * @param noFiles the number of files being logged * @param offset the offset into the file of this map page */ MapPage(int pgSz, int noFiles, int offset) { myOffset = offset; pageSize = pgSz; numFiles = (short)noFiles; oldEOF = new int[numFiles]; maxPages = (short)((pageSize - FIXED_SIZE - (4 * numFiles)) / 4); offsets = new int[maxPages]; } /** Set EOF array * @param files array of files * @exception StorageException I/O error determining EOF */ void setEOFs(RandomAccessFile files[] ) throws StorageException { try { for (int i = 0; i < numFiles; i++) { oldEOF[i] = (int)files[i].length(); } } catch (IOException ex) { throw new StorageIOException(ex); } } /** Get EOF for a file */ int getEOF(int index) { return oldEOF[index]; } /** create the next map page in a log filfilee * @param previous the previous map page for this file */ MapPage(MapPage previous) { this(previous.pageSize, previous.numFiles, previous.myOffset + ((previous.pageCount + 1) * previous.pageSize)); setTimeStamps(previous.timeStamp, previous.newTimeStamp); oldEOF = new int[previous.oldEOF.length]; System.arraycopy(previous.oldEOF, 0, oldEOF, 0, oldEOF.length); } /** Set the file ID for this map page * @param fileId new file id */ void setFileID(long id) { fileId = id; } /** set the time stamps for this map page * @param stamp the timestamp for the last comitted transaction * @param newStamp the timestamp for the currently outstanding transaction */ void setTimeStamps(long stamp, long newStamp) { timeStamp = stamp; newTimeStamp = newStamp; } /** write the map page to a file * @param file the file to write it to * @exception StorageException I/O error writing the page */ void write(RandomAccessFile file) throws StorageException { byte buffer[] = new byte[pageSize]; IntHolder offset = new IntHolder(0); checksum = computeChecksum(); Converter.writeInt(buffer, offset, pageSize); Converter.writeInt(buffer, offset, myOffset); Converter.writeShort(buffer, offset, numFiles); Converter.writeShort(buffer, offset, maxPages); Converter.writeShort(buffer, offset, pageCount); Converter.writeShort(buffer, offset, checksum); Converter.writeLong(buffer, offset, fileId); Converter.writeLong(buffer, offset, timeStamp); Converter.writeLong(buffer, offset, newTimeStamp); for (int i = 0; i < numFiles; i++) Converter.writeInt(buffer, offset, oldEOF[i]); for (int i = 0; i < pageCount; i++) Converter.writeInt(buffer, offset, offsets[i]); try { file.seek(myOffset); file.write(buffer); } catch (IOException ex) { throw new StorageIOException(ex); } } /** create a map page by reading from a file * @param file the file to read from * @param offset the offset in the file where the map page lives * @exception StorageException I/O error reading the file * @exception BadParameterException inconsistent page size */ MapPage(RandomAccessFile file, int offset, int pgSz) throws StorageException { byte buffer[] = new byte[pgSz]; try { file.seek(offset); file.readFully(buffer); } catch (IOException ex) { throw new StorageIOException(ex); } IntHolder index = new IntHolder(0); pageSize = Converter.readInt(buffer, index); if (pageSize == 0) { return; } else if (pageSize != pgSz) { throw new StoragePersistentDataException( MessageFormat.format( "Invalid page size {0}: {1} expected", new Object[] { new Integer(pgSz), new Integer(pageSize)})); } myOffset = Converter.readInt(buffer, index); numFiles = Converter.readShort(buffer, index); maxPages = Converter.readShort(buffer, index); pageCount = Converter.readShort(buffer, index); checksum = Converter.readShort(buffer, index); fileId = Converter.readLong(buffer, index); timeStamp = Converter.readLong(buffer, index); newTimeStamp = Converter.readLong(buffer, index); oldEOF = new int[numFiles]; offsets = new int[pageCount]; for (int i = 0; i < numFiles; i++) oldEOF[i] = Converter.readInt(buffer, index); for (int i = 0; i < pageCount; i++) offsets[i] = Converter.readInt(buffer, index); if (checksum != computeChecksum()) throw new StoragePersistentDataException( "Invalid checksum in MapPage"); } /** see if this was a page of zeros */ boolean isEmpty() { return pageSize == 0; } /** get next map page from log file * @exception StorageException I/O error reading the file * @exception BadParameterException inconsistent page size */ MapPage getNext(RandomAccessFile file, int numPages) throws StorageException { if (!isFull()) return null; int offset = myOffset + (pageSize * (pageCount + 1)); if (offset >= (numPages * pageSize)) return null; return new MapPage(file, offset, pageSize); } /** check that recovery parameters are consistent * @exception BadParameterException parameters inconsistent with * map page */ void checkParameters(int thePageSize, int theNumberOfFiles) throws StorageException { if (thePageSize != pageSize) { throw new StoragePersistentDataException( "Map page contains wrong page size."); } if (theNumberOfFiles != numFiles) { throw new StoragePersistentDataException( "Map page contains wrong number of files."); } } /** * check timestamps in logged file * @param file file which contains header * @exception StorageException I/O error opening or reading the file or * file header is corrupt */ void checkFileHeader(RandomAccessFile file) throws StorageException { FileHeader header = new FileHeader(file); if (header.timeStamp != timeStamp && header.timeStamp != newTimeStamp) { throw new StoragePersistentDataException( "Map page contains invalid timestamp" + + header.timeStamp + " valid would be " + timeStamp + " or " + newTimeStamp); } if (header.fileId != fileId) { throw new StoragePersistentDataException( "Map page contains invalid file id"); } } /** * where the next before-image page should be written to */ int nextPageOffset() { return myOffset + (pageCount + 1) * pageSize; } /** add a page to the map * @param page page to add */ void add(CachedPage page) { offsets[pageCount++] = encode(page.key); } /** is this page full */ boolean isFull() { return pageCount == maxPages; } /* encode file index and offset into an int */ private int encode(PageID page) { return (page.fileIndex << 20) | (page.offset / pageSize); } /* decode file index and offset from an int */ private PageID decode(int pageID) { return new PageID(pageID >>> 20, (pageID & 0XFFFFF) * pageSize); } /** cacluate the checksum for this map page */ short computeChecksum() { int sum = 0; sum += fileId; sum += timeStamp; sum += newTimeStamp; sum += pageCount; for (int i = 0; i < numFiles; i++) sum += (oldEOF[i]); for (int i = 0; i < pageCount; i++) sum += offsets[i]; return (short) ((sum & 0xFFFF) + (sum >>> 16)); } /** set files to their pre-transaction size * @exception StorageException I/O error truncating the files */ void truncateFiles(RandomAccessFile files[]) throws StorageException{ try { for (int i = 0; i < files.length; i++) { files[i].setLength(oldEOF[i]); } } catch (IOException ex) { throw new StorageIOException(ex); } } /** restore all of the before pages listed in this map page * @exception StorageException I/O error restoring the pages */ void recover(RandomAccessFile files[], RandomAccessFile logFile, int numPages, byte buffer[]) throws StorageException { try { for (int i = 0; i < pageCount; i++) { int logOffset = myOffset + (pageSize * (i + 1)); if (logOffset >= (numPages * pageSize)) break; PageID entry = decode(offsets[i]); files[entry.fileIndex].seek(entry.offset); logFile.seek(logOffset); logFile.readFully(buffer); files[entry.fileIndex].write(buffer); } } catch (IOException ex) { throw new StorageIOException(ex); } } } |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.