KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > inside > freespace > FreespaceManagerIx


1 /* Copyright (C) 2004 - 2006 db4objects Inc. http://www.db4o.com
2
3 This file is part of the db4o open source object database.
4
5 db4o is free software; you can redistribute it and/or modify it under
6 the terms of version 2 of the GNU General Public License as published
7 by the Free Software Foundation and as clarified by db4objects' GPL
8 interpretation policy, available at
9 http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
10 Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
11 Suite 350, San Mateo, CA 94403, USA.
12
13 db4o is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License along
19 with this program; if not, write to the Free Software Foundation, Inc.,
20 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */

21 package com.db4o.inside.freespace;
22
23 import com.db4o.*;
24 import com.db4o.foundation.*;
25 import com.db4o.inside.ix.*;
26
27
28 public class FreespaceManagerIx extends FreespaceManager{
29     
30     private int _slotAddress;
31     
32     private FreespaceIxAddress _addressIx;
33     private FreespaceIxLength _lengthIx;
34     
35     private boolean _started;
36     
37     private Collection4 _xBytes;
38
39     FreespaceManagerIx(YapFile file){
40         super(file);
41     }
42     
43     private void add(int address, int length){
44         _addressIx.add(address, length);
45         _lengthIx.add(address, length);
46     }
47     
48     public void beginCommit() {
49         if(! started()){
50             return;
51         }
52         slotEntryToZeroes(_file, _slotAddress);
53     }
54     
55     public void debug(){
56         if(Debug.freespace){
57             System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
58             System.out.println("Dumping file based address index");
59             _addressIx.debug();
60             System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
61             System.out.println("Dumping file based length index");
62             _lengthIx.debug();
63             System.out.println("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
64         }
65     }
66     
67     public void endCommit() {
68         if( ! started()){
69             return;
70         }
71         if (Debug.xbytes) {
72             _xBytes = new Collection4();
73         }
74
75         _addressIx._index.commitFreeSpace(_lengthIx._index);
76         
77         YapWriter writer = new YapWriter(_file.getSystemTransaction(), _slotAddress, slotLength());
78         _addressIx._index._metaIndex.write(writer);
79         _lengthIx._index._metaIndex.write(writer);
80         if (Debug.xbytes) {
81             writer.setID(YapConst.IGNORE_ID); // no XBytes check
82
}
83         if(_file.configImpl().flushFileBuffers()){
84             _file.syncFiles();
85         }
86         writer.writeEncrypt();
87         
88         if(Debug.xbytes){
89             Iterator4 i = _xBytes.iterator();
90             _xBytes = null;
91             while(i.moveNext()){
92                 int[] addressLength = (int[])i.current();
93                 writeXBytes(addressLength[0], addressLength[1]);
94             }
95         }
96     }
97     
98     public int entryCount() {
99         return _addressIx.entryCount();
100     }
101     
102     public void free(int address, int length) {
103         
104         if(! started()){
105             return;
106         }
107         
108         if (address <= 0) {
109             return;
110         }
111         
112         if (length <= discardLimit()) {
113             return;
114         }
115         
116         if(DTrace.enabled){
117             DTrace.FREE.logLength(address, length);
118         }
119         
120         length = _file.blocksFor(length);
121         
122         int freedAddress = address;
123         int freedLength = length;
124         
125         _addressIx.find(address);
126         
127         if(_addressIx.preceding()){
128             if(_addressIx.address() + _addressIx.length() == address){
129                 remove(_addressIx.address(), _addressIx.length());
130                 address = _addressIx.address();
131                 length += _addressIx.length();
132                 _addressIx.find(freedAddress);
133             }
134         }
135         
136         if(_addressIx.subsequent()){
137             if(freedAddress + freedLength == _addressIx.address()){
138                 remove(_addressIx.address(), _addressIx.length());
139                 length += _addressIx.length();
140             }
141         }
142         
143         add(address, length);
144         
145         if (Debug.xbytes) {
146             writeXBytes(freedAddress, freedLength);
147         }
148     }
149     
150     public void freeSelf() {
151         if(! started()){
152             return;
153         }
154         _addressIx._index._metaIndex.free(_file);
155         _lengthIx._index._metaIndex.free(_file);
156     }
157     
158     public int freeSize() {
159         return _addressIx.freeSize();
160     }
161
162     public int getSlot(int length) {
163         if(! started()){
164             return 0;
165         }
166         int address = getSlot1(length);
167         
168         if(address != 0){
169             if(DTrace.enabled){
170                 DTrace.GET_FREESPACE.logLength(address, length);
171             }
172         }
173         return address;
174     }
175
176     private int getSlot1(int length) {
177         
178         if(! started()){
179             return 0;
180         }
181         
182         length = _file.blocksFor(length);
183         
184         _lengthIx.find(length);
185         
186         if(_lengthIx.match()){
187             remove(_lengthIx.address(), _lengthIx.length());
188             return _lengthIx.address();
189         }
190         
191         if(_lengthIx.subsequent()){
192             
193             int lengthRemainder = _lengthIx.length() - length;
194             int addressRemainder = _lengthIx.address() + length;
195             remove(_lengthIx.address(), _lengthIx.length());
196             add(addressRemainder, lengthRemainder);
197             return _lengthIx.address();
198         }
199         
200         return 0;
201     }
202
203     public void migrate(final FreespaceManager newFM) {
204         if(! started()){
205             return;
206         }
207         final IntObjectVisitor addToNewFM = new IntObjectVisitor(){
208             public void visit(int length, Object JavaDoc address) {
209                 newFM.free(((Integer JavaDoc)address).intValue(), length);
210             }
211         };
212         Tree.traverse(_addressIx._indexTrans.getRoot(), new Visitor4() {
213             public void visit(Object JavaDoc a_object) {
214                 IxTree ixTree = (IxTree)a_object;
215                 ixTree.visitAll(addToNewFM);
216             }
217         });
218     }
219     
220     public void onNew(YapFile file) {
221         file.ensureFreespaceSlot();
222     }
223     
224     public void read(int freespaceID) {
225         // this is done in start(), nothing to do here
226
}
227
228     private void remove(int address, int length){
229         _addressIx.remove(address, length);
230         _lengthIx.remove(address, length);
231     }
232     
233     public void start(int slotAddress) {
234         
235         if(started()){
236             return;
237         }
238         
239         _slotAddress = slotAddress;
240         
241         MetaIndex miAddress = new MetaIndex();
242         MetaIndex miLength = new MetaIndex();
243         
244         YapReader reader = new YapReader(slotLength());
245         reader.read(_file, slotAddress, 0);
246         miAddress.read(reader);
247         miLength.read(reader);
248         
249         _addressIx = new FreespaceIxAddress(_file, miAddress);
250         _lengthIx = new FreespaceIxLength(_file, miLength);
251         
252         _started = true;
253     }
254     
255
256     private boolean started(){
257         return _started;
258     }
259     
260     public byte systemType() {
261         return FM_IX;
262     }
263
264     public int write(boolean shuttingDown) {
265         return 0; // no special ID, FreespaceIX information is stored in fileheader variable part
266
}
267
268     private void writeXBytes(int address, int length){
269         if (Debug.xbytes) {
270             if(_xBytes == null){
271                 length = length * blockSize();
272                 _file.debugWriteXBytes(address, length);
273             }else{
274                 _xBytes.add(new int[] {address, length});
275             }
276         }
277     }
278
279 }
280
Popular Tags