KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > hsqldb > persist > DataFileBlockManager


1 /* Copyright (c) 2001-2005, The HSQL Development Group
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9  *
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  *
14  * Neither the name of the HSQL Development Group nor the names of its
15  * contributors may be used to endorse or promote products derived from this
16  * software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
22  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */

30
31
32 package org.hsqldb.persist;
33
34 import org.hsqldb.lib.DoubleIntIndex;
35
36 /**
37  * Maintains a list of free file blocks with fixed capacity.<p>
38  *
39  * @author fredt@users
40  * @version 1.8.0
41  * @since 1.8.0
42  */

43 public class DataFileBlockManager {
44
45     private DoubleIntIndex lookup;
46     private final int capacity;
47     private int midSize;
48     private final int scale;
49     private long releaseCount;
50     private long requestCount;
51     private long requestSize;
52
53     // reporting vars
54
long lostFreeBlockSize;
55     boolean isModified;
56
57     /**
58      *
59      */

60     public DataFileBlockManager(int capacity, int scale, long lostSize) {
61
62         lookup = new DoubleIntIndex(capacity, true);
63
64         lookup.setValuesSearchTarget();
65
66         this.capacity = capacity;
67         this.scale = scale;
68         this.lostFreeBlockSize = lostSize;
69         this.midSize = 128; // arbitrary initial value
70
}
71
72     /**
73      */

74     void add(int pos, int rowSize) {
75
76         isModified = true;
77
78         if (capacity == 0) {
79             lostFreeBlockSize += rowSize;
80
81             return;
82         }
83
84         releaseCount++;
85
86         //
87
if (lookup.size() == capacity) {
88             resetList();
89         }
90
91         lookup.add(pos, rowSize);
92     }
93
94     /**
95      * Returns the position of a free block or 0.
96      */

97     int get(int rowSize) {
98
99         if (lookup.size() == 0) {
100             return -1;
101         }
102
103         int index = lookup.findFirstGreaterEqualKeyIndex(rowSize);
104
105         if (index == -1) {
106             return -1;
107         }
108
109         // statistics for successful requests only - to be used later for midSize
110
requestCount++;
111
112         requestSize += rowSize;
113
114         int length = lookup.getValue(index);
115         int difference = length - rowSize;
116         int key = lookup.getKey(index);
117
118         lookup.remove(index);
119
120         if (difference >= midSize) {
121             int pos = key + (rowSize / scale);
122
123             lookup.add(pos, difference);
124         } else {
125             lostFreeBlockSize += difference;
126         }
127
128         return key;
129     }
130
131     int size() {
132         return lookup.size();
133     }
134
135     long getLostBlocksSize() {
136         return lostFreeBlockSize;
137     }
138
139     boolean isModified() {
140         return isModified;
141     }
142
143     void clear() {
144         removeBlocks(lookup.size());
145     }
146
147     private void resetList() {
148
149         if (requestCount != 0) {
150             midSize = (int) (requestSize / requestCount);
151         }
152
153         int first = lookup.findFirstGreaterEqualSlotIndex(midSize);
154
155         if (first < lookup.size() / 4) {
156             first = lookup.size() / 4;
157         }
158
159         removeBlocks(first);
160     }
161
162     private void removeBlocks(int blocks) {
163
164         for (int i = 0; i < blocks; i++) {
165             lostFreeBlockSize += lookup.getValue(i);
166         }
167
168         lookup.removeRange(0, blocks);
169     }
170
171     private void checkIntegrity() throws NullPointerException JavaDoc {}
172 }
173
Popular Tags