001: /* Copyright (C) 2004 - 2007 db4objects Inc. http://www.db4o.com
002:
003: This file is part of the db4o open source object database.
004:
005: db4o is free software; you can redistribute it and/or modify it under
006: the terms of version 2 of the GNU General Public License as published
007: by the Free Software Foundation and as clarified by db4objects' GPL
008: interpretation policy, available at
009: http://www.db4o.com/about/company/legalpolicies/gplinterpretation/
010: Alternatively you can write to db4objects, Inc., 1900 S Norfolk Street,
011: Suite 350, San Mateo, CA 94403, USA.
012:
013: db4o is distributed in the hope that it will be useful, but WITHOUT ANY
014: WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: for more details.
017:
018: You should have received a copy of the GNU General Public License along
019: with this program; if not, write to the Free Software Foundation, Inc.,
020: 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
021: package com.db4o.internal.btree;
022:
023: import com.db4o.foundation.*;
024: import com.db4o.internal.*;
025: import com.db4o.internal.btree.algebra.*;
026:
027: /**
028: * @exclude
029: */
030: public class BTreeRangeSingle implements BTreeRange {
031:
032: public static final Comparison4 COMPARISON = new Comparison4() {
033: public int compare(Object x, Object y) {
034: BTreeRangeSingle xRange = (BTreeRangeSingle) x;
035: BTreeRangeSingle yRange = (BTreeRangeSingle) y;
036: return xRange.first().compareTo(yRange.first());
037: }
038: };
039:
040: private final Transaction _transaction;
041:
042: private final BTree _btree;
043:
044: private final BTreePointer _first;
045:
046: private final BTreePointer _end;
047:
048: public BTreeRangeSingle(Transaction transaction, BTree btree,
049: BTreePointer first, BTreePointer end) {
050: if (transaction == null || btree == null) {
051: throw new ArgumentNullException();
052: }
053: _transaction = transaction;
054: _btree = btree;
055: _first = first;
056: _end = end;
057: }
058:
059: public void accept(BTreeRangeVisitor visitor) {
060: visitor.visit(this );
061: }
062:
063: public boolean isEmpty() {
064: return BTreePointer.equals(_first, _end);
065: }
066:
067: public int size() {
068: if (isEmpty()) {
069: return 0;
070: }
071:
072: // TODO: This was an attempt to improve size calculation.
073: // Since all nodes are read, there is no improvement.
074:
075: // BTreeNode currentNode = _first.node();
076: // int sizeOnFirst = currentNode.count() - _first.index();
077: //
078: // BTreeNode endNode = _end == null ? null : _end.node();
079: // int substractForEnd =
080: // (endNode == null) ? 0 : (endNode.count() - _end.index());
081: //
082: // int size = sizeOnFirst - substractForEnd;
083: // while(! currentNode.equals(endNode)){
084: // currentNode = currentNode.nextNode();
085: // if(currentNode == null){
086: // break;
087: // }
088: // currentNode.prepareRead(transaction());
089: // size += currentNode.count();
090: // }
091: // return size;
092:
093: int size = 0;
094: final Iterator4 i = keys();
095: while (i.moveNext()) {
096: ++size;
097: }
098: return size;
099: }
100:
101: public Iterator4 pointers() {
102: return new BTreeRangePointerIterator(this );
103: }
104:
105: public Iterator4 keys() {
106: return new BTreeRangeKeyIterator(this );
107: }
108:
109: public final BTreePointer end() {
110: return _end;
111: }
112:
113: public Transaction transaction() {
114: return _transaction;
115: }
116:
117: public BTreePointer first() {
118: return _first;
119: }
120:
121: public BTreeRange greater() {
122: return newBTreeRangeSingle(_end, null);
123: }
124:
125: public BTreeRange union(BTreeRange other) {
126: if (null == other) {
127: throw new ArgumentNullException();
128: }
129: return new BTreeRangeSingleUnion(this ).dispatch(other);
130: }
131:
132: public boolean adjacent(BTreeRangeSingle range) {
133: return BTreePointer.equals(_end, range._first)
134: || BTreePointer.equals(range._end, _first);
135: }
136:
137: public boolean overlaps(BTreeRangeSingle range) {
138: return firstOverlaps(this , range) || firstOverlaps(range, this );
139: }
140:
141: private boolean firstOverlaps(BTreeRangeSingle x, BTreeRangeSingle y) {
142: return BTreePointer.lessThan(y._first, x._end)
143: && BTreePointer.lessThan(x._first, y._end);
144: }
145:
146: public BTreeRange extendToFirst() {
147: return newBTreeRangeSingle(firstBTreePointer(), _end);
148: }
149:
150: public BTreeRange extendToLast() {
151: return newBTreeRangeSingle(_first, null);
152: }
153:
154: public BTreeRange smaller() {
155: return newBTreeRangeSingle(firstBTreePointer(), _first);
156: }
157:
158: public BTreeRangeSingle newBTreeRangeSingle(BTreePointer first,
159: BTreePointer end) {
160: return new BTreeRangeSingle(transaction(), _btree, first, end);
161: }
162:
163: public BTreeRange newEmptyRange() {
164: return newBTreeRangeSingle(null, null);
165: }
166:
167: private BTreePointer firstBTreePointer() {
168: return btree().firstPointer(transaction());
169: }
170:
171: private BTree btree() {
172: return _btree;
173: }
174:
175: public BTreeRange intersect(BTreeRange range) {
176: if (null == range) {
177: throw new ArgumentNullException();
178: }
179: return new BTreeRangeSingleIntersect(this ).dispatch(range);
180: }
181:
182: public BTreeRange extendToLastOf(BTreeRange range) {
183: BTreeRangeSingle rangeImpl = checkRangeArgument(range);
184: return newBTreeRangeSingle(_first, rangeImpl._end);
185: }
186:
187: public String toString() {
188: return "BTreeRangeSingle(first=" + _first + ", end=" + _end
189: + ")";
190: }
191:
192: private BTreeRangeSingle checkRangeArgument(BTreeRange range) {
193: if (null == range) {
194: throw new ArgumentNullException();
195: }
196: BTreeRangeSingle rangeImpl = (BTreeRangeSingle) range;
197: if (btree() != rangeImpl.btree()) {
198: throw new IllegalArgumentException();
199: }
200: return rangeImpl;
201: }
202:
203: public BTreePointer lastPointer() {
204: if (_end == null) {
205: return btree().lastPointer(transaction());
206: }
207: return _end.previous();
208: }
209:
210: }
|