KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > db4o > inside > ix > IxFileRangeReader


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.ix;
22
23 import com.db4o.*;
24 import com.db4o.foundation.Tree;
25
26
27 /**
28  * @exclude
29  */

30 class IxFileRangeReader {
31
32     private int _baseAddress;
33     private int _baseAddressOffset;
34     private int _addressOffset;
35
36     private final Indexable4 _handler;
37
38     private int _lower;
39     private int _upper;
40     private int _cursor;
41
42     private final YapReader _reader;
43
44     final int _slotLength;
45
46     final int _linkLegth;
47
48     IxFileRangeReader(Indexable4 handler) {
49         _handler = handler;
50         _linkLegth = handler.linkLength();
51         _slotLength = _linkLegth + YapConst.INT_LENGTH;
52         _reader = new YapReader(_slotLength);
53     }
54
55     Tree add(IxFileRange fileRange, final Tree newTree) {
56         setFileRange(fileRange);
57         YapFile yf = fileRange.stream();
58         Transaction trans = fileRange.trans();
59         while (true) {
60             _reader.read(yf, _baseAddress, _baseAddressOffset + _addressOffset);
61             _reader._offset = 0;
62
63             int cmp = compare(trans);
64
65             if (cmp == 0) {
66                 int parentID = _reader.readInt();
67                 cmp = parentID - ((IxPatch) newTree)._parentID;
68             }
69             if (cmp > 0) {
70                 _upper = _cursor - 1;
71                 if (_upper < _lower) {
72                     _upper = _lower;
73                 }
74             } else if (cmp < 0) {
75                 _lower = _cursor + 1;
76                 if (_lower > _upper) {
77                     _lower = _upper;
78                 }
79             } else {
80                 if (newTree instanceof IxRemove) {
81                     if (_cursor == 0) {
82                         newTree._preceding = fileRange._preceding;
83                         if (fileRange._entries == 1) {
84                             newTree._subsequent = fileRange._subsequent;
85                             return newTree.balanceCheckNulls();
86                         }
87                         fileRange._entries--;
88                         fileRange.incrementAddress(_slotLength);
89                         fileRange._preceding = null;
90                         newTree._subsequent = fileRange;
91                     } else if (_cursor + 1 == fileRange._entries) {
92                         newTree._preceding = fileRange;
93                         newTree._subsequent = fileRange._subsequent;
94                         fileRange._subsequent = null;
95                         fileRange._entries--;
96                     } else {
97                         return insert(fileRange, newTree, _cursor, 0);
98                     }
99                     fileRange.calculateSize();
100                     return newTree.balanceCheckNulls();
101                 }
102                 if (_cursor == 0) {
103                     newTree._subsequent = fileRange;
104                     return newTree.rotateLeft();
105                 } else if (_cursor == fileRange._entries) {
106                     newTree._preceding = fileRange;
107                     return newTree.rotateRight();
108                 }
109                 return insert(fileRange, newTree, _cursor, cmp);
110             }
111             if (!adjustCursor()) {
112                 if (_cursor == 0 && cmp > 0) {
113                     return fileRange.add(newTree, 1);
114                 }
115                 if (_cursor == fileRange._entries - 1 && cmp < 0) {
116                     return fileRange.add(newTree, -1);
117                 }
118                 return insert(fileRange, newTree, _cursor, cmp);
119             }
120         }
121     }
122
123     private boolean adjustCursor() {
124         if (_upper < _lower) {
125             return false;
126         }
127         int oldCursor = _cursor;
128         _cursor = _lower + ((_upper - _lower) / 2);
129         if (_cursor == oldCursor && _cursor == _lower && _lower < _upper) {
130             _cursor++;
131         }
132         _addressOffset = _cursor * _slotLength;
133         return _cursor != oldCursor;
134     }
135
136     int compare(IxFileRange fileRange, int[] matches) {
137
138         setFileRange(fileRange);
139         YapFile yf = fileRange.stream();
140         Transaction trans = fileRange.trans();
141
142         int res = 0;
143
144         while (true) {
145             _reader.read(yf, _baseAddress, _baseAddressOffset + _addressOffset);
146             _reader._offset = 0;
147             int cmp = compare(trans);
148             if (cmp > 0) {
149                 _upper = _cursor - 1;
150             } else if (cmp < 0) {
151                 _lower = _cursor + 1;
152             } else {
153                 break;
154             }
155             if (!adjustCursor()) {
156                 if(_cursor <= 0){
157                     if( ! (cmp < 0 && fileRange._entries > 1) ){
158                         res = cmp;
159                     }
160                 }else if(_cursor >= (fileRange._entries - 1 ) ){
161                     if(cmp < 0){
162                         res = cmp;
163                     }
164                 }
165                 break;
166             }
167         }
168
169         matches[0] = _lower;
170         matches[1] = _upper;
171
172         if (_lower > _upper) {
173             return res;
174         }
175
176         int tempCursor = _cursor;
177         _upper = _cursor;
178         adjustCursor();
179         while (true) {
180             _reader.read(yf, _baseAddress, _baseAddressOffset + _addressOffset);
181             _reader._offset = 0;
182             int cmp = compare(trans);
183             if (cmp == 0) {
184                 _upper = _cursor;
185             } else {
186                 _lower = _cursor + 1;
187                 if (_lower > _upper) {
188                     matches[0] = _upper;
189                     break;
190                 }
191             }
192             if (!adjustCursor()) {
193                 matches[0] = _upper;
194                 break;
195             }
196         }
197         _upper = matches[1];
198         _lower = tempCursor;
199         if (_lower > _upper) {
200             _lower = _upper;
201         }
202         adjustCursor();
203         while (true) {
204             _reader.read(yf, _baseAddress, _baseAddressOffset + _addressOffset);
205             _reader._offset = 0;
206             int cmp = compare(trans);
207             if (cmp == 0) {
208                 _lower = _cursor;
209             } else {
210                 _upper = _cursor - 1;
211                 if (_upper < _lower) {
212                     matches[1] = _lower;
213                     break;
214                 }
215             }
216             if (!adjustCursor()) {
217                 matches[1] = _lower;
218                 break;
219             }
220         }
221         return res;
222     }
223
224     private final int compare(Transaction trans) {
225         return _handler.compareTo(_handler
226             .comparableObject(trans, _handler.readIndexEntry(_reader)));
227     }
228
229     private Tree insert(IxFileRange fileRange, Tree a_new, int a_cursor, int a_cmp) {
230         int incStartNewAt = a_cmp <= 0 ? 1 : 0;
231         int newAddressOffset = (a_cursor + incStartNewAt) * _slotLength;
232         int newEntries = fileRange._entries - a_cursor - incStartNewAt;
233         if (Deploy.debug) {
234             if (newEntries == 0) {
235                 // A bug in P1Object made this happen.
236
// It looke like it occurs if (a_cmp == 0)
237
// We may have to deal with this again, if we get similar
238
// entries on the same object (indexing arrays),
239
// so (a_cmp == 0)
240
throw new RuntimeException JavaDoc("No zero new entries permitted here.");
241             }
242         }
243
244         fileRange._entries = a_cmp < 0 ? a_cursor + 1 : a_cursor;
245         IxFileRange ifr = new IxFileRange(fileRange._fieldTransaction, _baseAddress,
246             _baseAddressOffset + newAddressOffset, newEntries);
247         ifr._subsequent = fileRange._subsequent;
248         fileRange._subsequent = null;
249         a_new._preceding = fileRange.balanceCheckNulls();
250         a_new._subsequent = ifr.balanceCheckNulls();
251         return a_new.balance();
252     }
253
254     private void setFileRange(IxFileRange a_fr) {
255         _lower = 0;
256         _upper = a_fr._entries - 1;
257         _baseAddress = a_fr._address;
258         _baseAddressOffset = a_fr._addressOffset;
259         adjustCursor();
260     }
261 }
Popular Tags