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.ix;
022:
023: import com.db4o.foundation.Debug4;
024: import com.db4o.foundation.IntObjectVisitor;
025: import com.db4o.foundation.Tree;
026: import com.db4o.foundation.Visitor4;
027: import com.db4o.internal.*;
028: import com.db4o.internal.freespace.FreespaceVisitor;
029:
030: /**
031: * A range of index entries in the database file.
032: */
033: class IxFileRange extends IxTree {
034:
035: final int _address;
036: int _addressOffset;
037: int _entries;
038: private int[] _lowerAndUpperMatches;
039:
040: public IxFileRange(IndexTransaction a_ft, int a_address,
041: int addressOffset, int a_entries) {
042: super (a_ft);
043: _address = a_address;
044: _addressOffset = addressOffset;
045: _entries = a_entries;
046: _size = a_entries;
047: }
048:
049: public Tree add(final Tree a_new) {
050: return reader().add(this , a_new);
051: }
052:
053: public int compare(Tree a_to) {
054: _lowerAndUpperMatches = new int[2];
055: return reader().compare(this , _lowerAndUpperMatches);
056: }
057:
058: int[] lowerAndUpperMatch() {
059: return _lowerAndUpperMatches;
060: }
061:
062: private final IxFileRangeReader reader() {
063: return _fieldTransaction.i_index.fileRangeReader();
064: }
065:
066: public void incrementAddress(int length) {
067: _addressOffset += length;
068: }
069:
070: public int ownSize() {
071: return _entries;
072: }
073:
074: public String toString() {
075: if (!Debug4.prettyToStrings) {
076: return super .toString();
077: }
078: Buffer fileReader = new Buffer(slotLength());
079: final StringBuffer sb = new StringBuffer();
080: sb.append("IxFileRange");
081: visitAll(new IntObjectVisitor() {
082: public void visit(int anInt, Object anObject) {
083: sb.append("\n ");
084: sb.append("Parent: " + anInt);
085: sb.append("\n ");
086: sb.append(anObject);
087: }
088: });
089: return sb.toString();
090: }
091:
092: public void visit(Object obj) {
093: visit((Visitor4) obj, null);
094: }
095:
096: public void visit(Visitor4 visitor, int[] lowerUpper)
097: throws IxException {
098: IxFileRangeReader frr = reader();
099: if (lowerUpper == null) {
100: lowerUpper = new int[] { 0, _entries - 1 };
101: }
102: int count = lowerUpper[1] - lowerUpper[0] + 1;
103: if (count > 0) {
104: Buffer fileReader = new Buffer(count * frr._slotLength);
105: int offset = _addressOffset
106: + (lowerUpper[0] * frr._slotLength);
107: fileReader.read(stream(), _address, offset);
108: for (int i = lowerUpper[0]; i <= lowerUpper[1]; i++) {
109: fileReader.incrementOffset(frr._linkLegth);
110: visitor.visit(new Integer(fileReader.readInt()));
111: }
112: }
113: }
114:
115: public int write(Indexable4 a_handler, StatefulBuffer a_writer) {
116: LocalObjectContainer yf = (LocalObjectContainer) a_writer
117: .getStream();
118: int length = _entries * slotLength();
119: yf.copy(_address, _addressOffset, a_writer.getAddress(),
120: a_writer.addressOffset(), length);
121: a_writer.moveForward(length);
122: return _entries;
123: }
124:
125: public void visitAll(IntObjectVisitor visitor) throws IxException {
126: LocalObjectContainer yf = stream();
127: Transaction transaction = trans();
128: Buffer fileReader = new Buffer(slotLength());
129: for (int i = 0; i < _entries; i++) {
130: int address = _address + (i * slotLength());
131: fileReader.read(yf, address, _addressOffset);
132: fileReader._offset = 0;
133: Object obj = IxDeprecationHelper.comparableObject(
134: handler(), transaction, handler().readIndexEntry(
135: fileReader));
136: visitor.visit(fileReader.readInt(), obj);
137: }
138:
139: }
140:
141: public void visitFirst(FreespaceVisitor visitor) {
142: if (_preceding != null) {
143: ((IxTree) _preceding).visitFirst(visitor);
144: if (visitor.visited()) {
145: return;
146: }
147: }
148: freespaceVisit(visitor, 0);
149: }
150:
151: public void visitLast(FreespaceVisitor visitor) {
152: if (_subsequent != null) {
153: ((IxTree) _subsequent).visitLast(visitor);
154: if (visitor.visited()) {
155: return;
156: }
157: }
158: freespaceVisit(visitor, _entries - 1);
159: }
160:
161: public void freespaceVisit(FreespaceVisitor visitor, int index) {
162: IxFileRangeReader frr = reader();
163: Buffer fileReader = new Buffer(frr._slotLength);
164: fileReader.read(stream(), _address, _addressOffset
165: + (index * frr._slotLength));
166: int val = fileReader.readInt();
167: int parentID = fileReader.readInt();
168: visitor.visit(parentID, val);
169: }
170:
171: public Object shallowClone() {
172: IxFileRange range = new IxFileRange(_fieldTransaction,
173: _address, _addressOffset, _entries);
174: super .shallowCloneInternal(range);
175: if (_lowerAndUpperMatches != null) {
176: range._lowerAndUpperMatches = new int[] {
177: _lowerAndUpperMatches[0], _lowerAndUpperMatches[1] };
178: }
179: return range;
180: }
181: }
|