001: /*
002: This source file is part of Smyle, a database library.
003: For up-to-date information, see http://www.drjava.de/smyle
004: Copyright (C) 2001 Stefan Reich (doc@drjava.de)
005:
006: This library is free software; you can redistribute it and/or
007: modify it under the terms of the GNU Lesser General Public
008: License as published by the Free Software Foundation; either
009: version 2.1 of the License, or (at your option) any later version.
010:
011: This library is distributed in the hope that it will be useful,
012: but WITHOUT ANY WARRANTY; without even the implied warranty of
013: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: Lesser General Public License for more details.
015:
016: You should have received a copy of the GNU Lesser General Public
017: License along with this library; if not, write to the Free Software
018: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
019:
020: For full license text, see doc/license/lgpl.txt in this distribution
021: */
022:
023: package drjava.smyle.core;
024:
025: import java.io.*;
026: import java.util.*;
027: import java.lang.Object;
028: import java.lang.ref.*;
029: import org.artsProject.mcop.*;
030: import org.artsProject.mcop.core.*;
031: import org.artsProject.util.*;
032: import drjava.smyle.*;
033: import drjava.smyle.meta.*;
034:
035: final class SortedIterator<T extends Struct<T>> implements
036: TableIterator<T> {
037: TableImpl<T> table;
038: Filter<T> filter;
039: int expectedModCount;
040: int i = 0;
041: ArrayList<Entry> entries = new ArrayList<Entry>();
042:
043: class Entry implements Comparable {
044: Comparable[] key;
045: ChunkRef chunk;
046:
047: Entry(Comparable[] key, ChunkRef chunk) {
048: this .key = key;
049: this .chunk = chunk;
050: }
051:
052: public int compareTo(Object o) {
053: for (int i = 0; i < key.length; i++) {
054: int c = key[i].compareTo(((Entry) o).key[i]);
055: if (c != 0) {
056: return filter.isReversed() ? -c : c;
057: }
058: }
059: return 0;
060: }
061: }
062:
063: SortedIterator(TableImpl<T> table, TableIterator<T> iterator,
064: Filter<T> filter) {
065: this .table = table;
066: expectedModCount = table.modCount;
067: this .filter = filter;
068: scan(iterator);
069: }
070:
071: private void checkForComodification() {
072: if (table.modCount != expectedModCount)
073: throw new ConcurrentModificationException();
074: }
075:
076: public boolean hasNext() {
077: checkForComodification();
078: return i < entries.size();
079: }
080:
081: public T next() {
082: checkForComodification();
083: return table.loadElement(entries.get(i++).chunk);
084: }
085:
086: public ChunkRef nextChunk() {
087: checkForComodification();
088: return entries.get(i++).chunk;
089: }
090:
091: public void remove() {
092: checkForComodification();
093: ++expectedModCount;
094: table.removeChunk(entries.get(--i).chunk.index);
095: }
096:
097: void scan(TableIterator<T> iterator) {
098: // gather keys and chunkrefs
099:
100: Function<T, Comparable> order = filter._getOrder().get(0);
101: while (iterator.hasNext()) {
102: ChunkRef cr = iterator.nextChunk();
103: T t = table.loadElement(cr);
104: /*if (filter != null && !filter.matches(t))
105: continue;*/
106: Comparable[] key = new Comparable[filter._getOrder().size()];
107: for (int i = 0; i < key.length; i++)
108: key[i] = filter._getOrder().get(i).of(t);
109: entries.add(new Entry(key, cr));
110: }
111:
112: // sort
113:
114: Collections.sort(entries);
115: }
116: }
|