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: FreeLogicalRowIdPage.java,v 1.1 2000/05/06 00:00:31 boisvert Exp $ 46 */ 47 48 package jdbm.recman; 49 50 /** 51 * Class describing a page that holds logical rowids that were freed. Note 52 * that the methods have *physical* rowids in their signatures - this is 53 * because logical and physical rowids are internally the same, only their 54 * external representation (i.e. in the client API) differs. 55 */ 56 class FreeLogicalRowIdPage extends PageHeader { 57 // offsets 58 private static final short O_COUNT = PageHeader.SIZE; // short count 59 static final short O_FREE = (short)(O_COUNT + Magic.SZ_SHORT); 60 static final short ELEMS_PER_PAGE = (short) 61 ((RecordFile.BLOCK_SIZE - O_FREE) / PhysicalRowId.SIZE); 62 63 // slots we returned. 64 final PhysicalRowId[] slots = new PhysicalRowId[ELEMS_PER_PAGE]; 65 66 /** 67 * Constructs a data page view from the indicated block. 68 */ 69 FreeLogicalRowIdPage(BlockIo block) { 70 super(block); 71 } 72 73 /** 74 * Factory method to create or return a data page for the 75 * indicated block. 76 */ 77 static FreeLogicalRowIdPage getFreeLogicalRowIdPageView(BlockIo block) { 78 79 BlockView view = block.getView(); 80 if (view != null && view instanceof FreeLogicalRowIdPage) 81 return (FreeLogicalRowIdPage) view; 82 else 83 return new FreeLogicalRowIdPage(block); 84 } 85 86 /** Returns the number of free rowids */ 87 short getCount() { 88 return block.readShort(O_COUNT); 89 } 90 91 /** Sets the number of free rowids */ 92 private void setCount(short i) { 93 block.writeShort(O_COUNT, i); 94 } 95 96 /** Frees a slot */ 97 void free(int slot) { 98 get(slot).setBlock(0); 99 setCount((short) (getCount() - 1)); 100 } 101 102 /** Allocates a slot */ 103 PhysicalRowId alloc(int slot) { 104 setCount((short) (getCount() + 1)); 105 get(slot).setBlock(-1); 106 return get(slot); 107 } 108 109 /** Returns true if a slot is allocated */ 110 boolean isAllocated(int slot) { 111 return get(slot).getBlock() > 0; 112 } 113 114 /** Returns true if a slot is free */ 115 boolean isFree(int slot) { 116 return !isAllocated(slot); 117 } 118 119 120 /** Returns the value of the indicated slot */ 121 PhysicalRowId get(int slot) { 122 if (slots[slot] == null) 123 slots[slot] = new PhysicalRowId(block, slotToOffset(slot));; 124 return slots[slot]; 125 } 126 127 /** Converts slot to offset */ 128 private short slotToOffset(int slot) { 129 return (short) (O_FREE + 130 (slot * PhysicalRowId.SIZE)); 131 } 132 133 /** 134 * Returns first free slot, -1 if no slots are available 135 */ 136 int getFirstFree() { 137 for (int i = 0; i < ELEMS_PER_PAGE; i++) { 138 if (isFree(i)) 139 return i; 140 } 141 return -1; 142 } 143 144 /** 145 * Returns first allocated slot, -1 if no slots are available. 146 */ 147 int getFirstAllocated() { 148 for (int i = 0; i < ELEMS_PER_PAGE; i++) { 149 if (isAllocated(i)) 150 return i; 151 } 152 return -1; 153 } 154 }