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.query.result;
022:
023: import com.db4o.foundation.*;
024: import com.db4o.internal.*;
025: import com.db4o.internal.btree.*;
026: import com.db4o.internal.classindex.*;
027: import com.db4o.internal.query.processor.*;
028: import com.db4o.query.*;
029: import com.db4o.reflect.*;
030:
031: /**
032: * @exclude
033: */
034: public class IdListQueryResult extends AbstractQueryResult implements
035: Visitor4 {
036:
037: private Tree _candidates;
038:
039: private boolean _checkDuplicates;
040:
041: public IntArrayList _ids;
042:
043: public IdListQueryResult(Transaction trans, int initialSize) {
044: super (trans);
045: _ids = new IntArrayList(initialSize);
046: }
047:
048: public IdListQueryResult(Transaction trans) {
049: this (trans, 0);
050: }
051:
052: public IntIterator4 iterateIDs() {
053: return _ids.intIterator();
054: }
055:
056: public Object get(int index) {
057: synchronized (lock()) {
058: return activatedObject(getId(index));
059: }
060: }
061:
062: public int getId(int index) {
063: if (index < 0 || index >= size()) {
064: throw new IndexOutOfBoundsException();
065: }
066: return _ids.get(index);
067: }
068:
069: public final void checkDuplicates() {
070: _checkDuplicates = true;
071: }
072:
073: public void visit(Object a_tree) {
074: QCandidate candidate = (QCandidate) a_tree;
075: if (candidate.include()) {
076: addKeyCheckDuplicates(candidate._key);
077: }
078: }
079:
080: public void addKeyCheckDuplicates(int a_key) {
081: if (_checkDuplicates) {
082: TreeInt newNode = new TreeInt(a_key);
083: _candidates = Tree.add(_candidates, newNode);
084: if (newNode._size == 0) {
085: return;
086: }
087: }
088: add(a_key);
089: }
090:
091: public void sort(final QueryComparator cmp) {
092: Algorithms4.qsort(new QuickSortable4() {
093: public void swap(int leftIndex, int rightIndex) {
094: _ids.swap(leftIndex, rightIndex);
095: }
096:
097: public int size() {
098: return IdListQueryResult.this .size();
099: }
100:
101: public int compare(int leftIndex, int rightIndex) {
102: return cmp.compare(get(leftIndex), get(rightIndex));
103: }
104: });
105: }
106:
107: public void loadFromClassIndex(ClassMetadata clazz) {
108: final ClassIndexStrategy index = clazz.index();
109: if (index instanceof BTreeClassIndexStrategy) {
110: BTree btree = ((BTreeClassIndexStrategy) index).btree();
111: _ids = new IntArrayList(btree.size(transaction()));
112: }
113: index.traverseAll(_transaction, new Visitor4() {
114: public void visit(Object a_object) {
115: add(((Integer) a_object).intValue());
116: }
117: });
118: }
119:
120: public void loadFromQuery(QQuery query) {
121: query.executeLocal(this );
122: }
123:
124: public void loadFromClassIndexes(ClassMetadataIterator iter) {
125:
126: // duplicates because of inheritance hierarchies
127: final Tree.ByRef duplicates = new Tree.ByRef();
128:
129: while (iter.moveNext()) {
130: final ClassMetadata yapClass = iter.currentClass();
131: if (yapClass.getName() != null) {
132: ReflectClass claxx = yapClass.classReflector();
133: if (claxx == null
134: || !(stream()._handlers.ICLASS_INTERNAL
135: .isAssignableFrom(claxx))) {
136: final ClassIndexStrategy index = yapClass.index();
137: index.traverseAll(_transaction, new Visitor4() {
138: public void visit(Object obj) {
139: int id = ((Integer) obj).intValue();
140: TreeInt newNode = new TreeInt(id);
141: duplicates.value = Tree.add(
142: duplicates.value, newNode);
143: if (newNode.size() != 0) {
144: add(id);
145: }
146: }
147: });
148: }
149: }
150: }
151:
152: }
153:
154: public void loadFromIdReader(Buffer reader) {
155: int size = reader.readInt();
156: for (int i = 0; i < size; i++) {
157: add(reader.readInt());
158: }
159: }
160:
161: public void add(int id) {
162: _ids.add(id);
163: }
164:
165: public int indexOf(int id) {
166: return _ids.indexOf(id);
167: }
168:
169: public int size() {
170: return _ids.size();
171: }
172:
173: }
|