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:
026: /**
027: * @exclude
028: */
029: public class BTreePointer {
030:
031: public static BTreePointer max(BTreePointer x, BTreePointer y) {
032: if (x == null) {
033: return x;
034: }
035: if (y == null) {
036: return y;
037: }
038: if (x.compareTo(y) > 0) {
039: return x;
040: }
041: return y;
042: }
043:
044: public static BTreePointer min(BTreePointer x, BTreePointer y) {
045: if (x == null) {
046: return y;
047: }
048: if (y == null) {
049: return x;
050: }
051: if (x.compareTo(y) < 0) {
052: return x;
053: }
054: return y;
055: }
056:
057: private final BTreeNode _node;
058:
059: private final int _index;
060:
061: private final Transaction _transaction;
062:
063: private final Buffer _nodeReader;
064:
065: public BTreePointer(Transaction transaction, Buffer nodeReader,
066: BTreeNode node, int index) {
067: if (transaction == null || node == null) {
068: throw new ArgumentNullException();
069: }
070: _transaction = transaction;
071: _nodeReader = nodeReader;
072: _node = node;
073: _index = index;
074: }
075:
076: public final Transaction transaction() {
077: return _transaction;
078: }
079:
080: public final int index() {
081: return _index;
082: }
083:
084: public final BTreeNode node() {
085: return _node;
086: }
087:
088: public final Object key() {
089: return node().key(transaction(), nodeReader(), index());
090: }
091:
092: private Buffer nodeReader() {
093: return _nodeReader;
094: }
095:
096: public BTreePointer next() {
097: int indexInMyNode = index() + 1;
098: while (indexInMyNode < node().count()) {
099: if (node().indexIsValid(transaction(), indexInMyNode)) {
100: return new BTreePointer(transaction(), nodeReader(),
101: node(), indexInMyNode);
102: }
103: indexInMyNode++;
104: }
105: int newIndex = -1;
106: BTreeNode nextNode = node();
107: Buffer nextReader = null;
108: while (newIndex == -1) {
109: nextNode = nextNode.nextNode();
110: if (nextNode == null) {
111: return null;
112: }
113: nextReader = nextNode.prepareRead(transaction());
114: newIndex = nextNode.firstKeyIndex(transaction());
115: }
116: return new BTreePointer(transaction(), nextReader, nextNode,
117: newIndex);
118: }
119:
120: public BTreePointer previous() {
121: int indexInMyNode = index() - 1;
122: while (indexInMyNode >= 0) {
123: if (node().indexIsValid(transaction(), indexInMyNode)) {
124: return new BTreePointer(transaction(), nodeReader(),
125: node(), indexInMyNode);
126: }
127: indexInMyNode--;
128: }
129: int newIndex = -1;
130: BTreeNode previousNode = node();
131: Buffer previousReader = null;
132: while (newIndex == -1) {
133: previousNode = previousNode.previousNode();
134: if (previousNode == null) {
135: return null;
136: }
137: previousReader = previousNode.prepareRead(transaction());
138: newIndex = previousNode.lastKeyIndex(transaction());
139: }
140: return new BTreePointer(transaction(), previousReader,
141: previousNode, newIndex);
142: }
143:
144: public boolean equals(Object obj) {
145: if (this == obj) {
146: return true;
147: }
148: if (!(obj instanceof BTreePointer)) {
149: return false;
150: }
151: BTreePointer other = (BTreePointer) obj;
152:
153: if (index() != other.index()) {
154: return false;
155: }
156:
157: return node().equals(other.node());
158: }
159:
160: public int hashCode() {
161: return node().hashCode();
162: }
163:
164: public String toString() {
165: return "BTreePointer(index=" + index() + ", node=" + node()
166: + ")";
167: }
168:
169: public int compareTo(BTreePointer y) {
170: if (null == y) {
171: throw new ArgumentNullException();
172: }
173: if (btree() != y.btree()) {
174: throw new IllegalArgumentException();
175: }
176: return btree().compareKeys(key(), y.key());
177: }
178:
179: private BTree btree() {
180: return node().btree();
181: }
182:
183: public static boolean lessThan(BTreePointer x, BTreePointer y) {
184: return BTreePointer.min(x, y) == x && !equals(x, y);
185: }
186:
187: public static boolean equals(BTreePointer x, BTreePointer y) {
188: if (x == null) {
189: return y == null;
190: }
191: return x.equals(y);
192: }
193:
194: public boolean isValid() {
195: return node().indexIsValid(transaction(), index());
196: }
197: }
|