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 }