summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/database/ids/integer
diff options
context:
space:
mode:
authorAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:38 +0000
committerAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:38 +0000
commit14a486343aef55f97f54082d6b542dedebf6f3ba (patch)
tree000fcc4968578771ad265079eef7617d66de2cda /src/de/lmu/ifi/dbs/elki/database/ids/integer
parent8300861dc4c62c5567a4e654976072f854217544 (diff)
Import Upstream version 0.6.0
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/database/ids/integer')
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java43
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java208
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java214
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java127
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java226
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java (renamed from src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNListHeap.java)218
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java339
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java234
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java157
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java3
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java38
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java167
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java81
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java2
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayDBIDs.java192
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayModifiableDBIDs.java155
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java45
-rw-r--r--src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java9
22 files changed, 1518 insertions, 948 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java
index 061deb08..72ecb9be 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/AbstractIntegerDBIDFactory.java
@@ -47,12 +47,12 @@ import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer;
* Abstract base class for DBID factories.
*
* @author Erich Schubert
- *
+ *
* @apiviz.uses IntegerDBID oneway - - «create»
* @apiviz.uses IntegerDBIDPair oneway - - «create»
* @apiviz.uses IntegerDBIDRange oneway - - «create»
- * @apiviz.uses TroveArrayModifiableDBIDs oneway - - «create»
* @apiviz.uses TroveHashSetModifiableDBIDs oneway - - «create»
+ * @apiviz.uses IntegerArrayDBIDs oneway - - «create»
*/
abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
/**
@@ -67,9 +67,10 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
@Override
public void assignVar(DBIDVar var, int val) {
- if (var instanceof IntegerDBIDVar) {
- ((IntegerDBIDVar)var).internalSetIndex(val);
- } else {
+ if(var instanceof IntegerDBIDVar) {
+ ((IntegerDBIDVar) var).internalSetIndex(val);
+ }
+ else {
var.set(new IntegerDBID(val));
}
}
@@ -139,7 +140,7 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
@SuppressWarnings("unchecked")
@Override
public <D extends Distance<D>> DistanceDBIDPair<D> newDistancePair(D val, DBIDRef id) {
- if (val instanceof DoubleDistance) {
+ if(val instanceof DoubleDistance) {
return (DistanceDBIDPair<D>) new DoubleDistanceIntegerDBIDPair(((DoubleDistance) val).doubleValue(), id.internalGetIndex());
}
return new DistanceIntegerDBIDPair<>(val, id.internalGetIndex());
@@ -149,12 +150,12 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
public DoubleDistanceDBIDPair newDistancePair(double val, DBIDRef id) {
return new DoubleDistanceIntegerDBIDPair(val, id.internalGetIndex());
}
-
+
@SuppressWarnings("unchecked")
@Override
public <D extends Distance<D>> KNNHeap<D> newHeap(D factory, int k) {
- if (factory instanceof DoubleDistance) {
- return (KNNHeap<D>) new DoubleDistanceIntegerDBIDKNNListHeap(k);
+ if(factory instanceof DoubleDistance) {
+ return (KNNHeap<D>) newDoubleDistanceHeap(k);
}
return new DistanceDBIDPairKNNHeap<>(k);
}
@@ -162,24 +163,34 @@ abstract class AbstractIntegerDBIDFactory implements DBIDFactory {
@SuppressWarnings("unchecked")
@Override
public <D extends Distance<D>> KNNHeap<D> newHeap(KNNList<D> exist) {
- if (exist instanceof DoubleDistanceKNNList) {
- DoubleDistanceKNNHeap heap = new DoubleDistanceIntegerDBIDKNNListHeap(exist.getK());
+ if(exist instanceof DoubleDistanceKNNList) {
+ DoubleDistanceKNNHeap heap = newDoubleDistanceHeap(exist.getK());
// Insert backwards, as this will produce a proper heap
- for (int i = exist.size() - 1; i >= 0; i--) {
- heap.add((DoubleDistanceDBIDPair) exist.get(i));
+ for(int i = exist.size() - 1; i >= 0; i--) {
+ heap.insert((DoubleDistanceDBIDPair) exist.get(i));
}
return (KNNHeap<D>) heap;
- } else {
+ }
+ else {
DistanceDBIDPairKNNHeap<D> heap = new DistanceDBIDPairKNNHeap<>(exist.getK());
// Insert backwards, as this will produce a proper heap
- for (int i = exist.size() - 1; i >= 0; i--) {
- heap.add(exist.get(i));
+ for(int i = exist.size() - 1; i >= 0; i--) {
+ heap.insert(exist.get(i));
}
return heap;
}
}
@Override
+ public DoubleDistanceKNNHeap newDoubleDistanceHeap(int k) {
+ // TODO: benchmark threshold!
+ if(k > 1000) {
+ return new DoubleDistanceIntegerDBIDKNNHeap(k);
+ }
+ return new DoubleDistanceIntegerDBIDSortedKNNList(k);
+ }
+
+ @Override
public ByteBufferSerializer<DBID> getDBIDSerializer() {
return IntegerDBID.DYNAMIC_SERIALIZER;
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java
index dfff45b4..2fc94ddb 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayModifiableIntegerDBIDs.java
@@ -47,7 +47,7 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
/**
* Occupied size.
*/
- private int size = 0;
+ private int size;
/**
* Initial size.
@@ -57,11 +57,12 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
/**
* Constructor.
*
- * @param size Initial size
+ * @param isize Initial size
*/
- protected ArrayModifiableIntegerDBIDs(int size) {
+ protected ArrayModifiableIntegerDBIDs(int isize) {
super();
- this.store = new int[size];
+ this.store = new int[isize < 3 ? 3 : isize];
+ // default this.size = 0;
}
/**
@@ -70,6 +71,7 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
protected ArrayModifiableIntegerDBIDs() {
super();
this.store = new int[INITIAL_SIZE];
+ // default: this.size = 0;
}
/**
@@ -79,7 +81,15 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
*/
protected ArrayModifiableIntegerDBIDs(DBIDs existing) {
this(existing.size());
- this.addDBIDs(existing);
+ if (existing instanceof IntegerDBIDRange) {
+ IntegerDBIDRange range = (IntegerDBIDRange) existing;
+ for (int i = 0; i < range.len; i++) {
+ store[i] = range.start + i;
+ }
+ size = range.len;
+ } else {
+ this.addDBIDs(existing);
+ }
}
@Override
@@ -99,10 +109,9 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
@Override
public void assignVar(int index, DBIDVar var) {
- if(var instanceof IntegerDBIDVar) {
+ if (var instanceof IntegerDBIDVar) {
((IntegerDBIDVar) var).internalSetIndex(store[index]);
- }
- else {
+ } else {
// less efficient, involves object creation.
var.set(get(index));
}
@@ -114,23 +123,32 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
* @param minsize Desired size
*/
private void ensureSize(int minsize) {
- int asize = store.length;
- // Ensure a minimum size, to not run into an infinite loop below!
- if (asize < 2) {
- asize = 2;
- }
- while(asize < minsize) {
- asize = (asize >> 1) + asize;
+ if (minsize <= store.length) {
+ return;
}
- if(asize > store.length) {
- store = Arrays.copyOf(store, asize);
+ int asize = store.length;
+ while (asize < minsize) {
+ asize = (asize >>> 1) + asize;
}
+ final int[] prev = store;
+ store = new int[asize];
+ System.arraycopy(prev, 0, store, 0, size);
+ }
+
+ /**
+ * Grow array by 50%.
+ */
+ private void grow() {
+ final int newsize = store.length + (store.length >>> 1);
+ final int[] prev = store;
+ store = new int[newsize];
+ System.arraycopy(prev, 0, store, 0, size);
}
@Override
public boolean addDBIDs(DBIDs ids) {
ensureSize(size + ids.size());
- for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
store[size] = iter.internalGetIndex();
++size;
}
@@ -140,11 +158,11 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
@Override
public boolean removeDBIDs(DBIDs ids) {
boolean success = false;
- for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
int rm = id.internalGetIndex();
// TODO: when sorted, use binary search!
- for(int i = 0; i < size; i++) {
- if(store[i] == rm) {
+ for (int i = 0; i < size; i++) {
+ if (store[i] == rm) {
--size;
store[i] = store[size];
success = true;
@@ -157,8 +175,8 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
@Override
public boolean add(DBIDRef e) {
- if(size == store.length) {
- ensureSize(size + 1);
+ if (size == store.length) {
+ grow();
}
store[size] = e.internalGetIndex();
++size;
@@ -169,8 +187,8 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
public boolean remove(DBIDRef o) {
int rm = o.internalGetIndex();
// TODO: when sorted, use binary search!
- for(int i = 0; i < size; i++) {
- if(store[i] == rm) {
+ for (int i = 0; i < size; i++) {
+ if (store[i] == rm) {
--size;
store[i] = store[size];
return true;
@@ -190,7 +208,7 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
public DBID remove(int index) {
DBID ret = new IntegerDBID(store[index]);
--size;
- if(size > 0) {
+ if (size > 0) {
store[index] = store[size];
}
return ret;
@@ -210,8 +228,8 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
public boolean contains(DBIDRef o) {
// TODO: recognize sorted arrays, then use binary search?
int oid = o.internalGetIndex();
- for(int i = 0; i < size; i++) {
- if(store[i] == oid) {
+ for (int i = 0; i < size; i++) {
+ if (store[i] == oid) {
return true;
}
}
@@ -241,7 +259,12 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
}
@Override
- public IntegerDBIDArrayMIter iter() {
+ public Slice slice(int begin, int end) {
+ return new Slice(begin, end);
+ }
+
+ @Override
+ public Itr iter() {
return new Itr();
}
@@ -303,4 +326,131 @@ public class ArrayModifiableIntegerDBIDs implements ArrayModifiableDBIDs, Intege
return Integer.toString(internalGetIndex()) + "@" + pos;
}
}
+
+ /**
+ * Slice of an array.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class Slice implements IntegerArrayDBIDs {
+ /**
+ * Slice positions.
+ */
+ final int begin, end;
+
+ /**
+ * Constructor.
+ *
+ * @param begin Begin, inclusive
+ * @param end End, exclusive
+ */
+ public Slice(int begin, int end) {
+ super();
+ this.begin = begin;
+ this.end = end;
+ }
+
+ @Override
+ public int size() {
+ return end - begin;
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ // TODO: recognize sorted arrays, then use binary search?
+ int oid = o.internalGetIndex();
+ for (int i = begin; i < end; i++) {
+ if (store[i] == oid) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return begin == end;
+ }
+
+ @Override
+ public DBID get(int i) {
+ return ArrayModifiableIntegerDBIDs.this.get(begin + i);
+ }
+
+ @Override
+ public void assignVar(int index, DBIDVar var) {
+ ArrayModifiableIntegerDBIDs.this.assignVar(begin + index, var);
+ }
+
+ @Override
+ public int binarySearch(DBIDRef key) {
+ return Arrays.binarySearch(store, begin, end, key.internalGetIndex()) - begin;
+ }
+
+ @Override
+ public SliceItr iter() {
+ return new SliceItr();
+ }
+
+ @Override
+ public Slice slice(int begin, int end) {
+ return new Slice(begin + begin, begin + end);
+ }
+
+ /**
+ * Iterator class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class SliceItr implements IntegerDBIDArrayIter {
+ /**
+ * Iterator position.
+ */
+ int pos = begin;
+
+ @Override
+ public int internalGetIndex() {
+ return store[pos];
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < end && pos >= begin;
+ }
+
+ @Override
+ public void advance() {
+ ++pos;
+ }
+
+ @Override
+ public int getOffset() {
+ return pos;
+ }
+
+ @Override
+ public void advance(int count) {
+ pos += count;
+ }
+
+ @Override
+ public void retract() {
+ --pos;
+ }
+
+ @Override
+ public void seek(int off) {
+ pos = off;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(internalGetIndex()) + "@" + pos;
+ }
+ }
+ }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java
index 4b4b5a42..fcb426ac 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/ArrayStaticIntegerDBIDs.java
@@ -36,14 +36,12 @@ import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
* Static (no modifications allowed) set of Database Object IDs.
*
* @author Erich Schubert
- *
- * @apiviz.has IntegerDBID
*/
public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
/**
* The actual storage.
*/
- protected int[] ids;
+ protected int[] store;
/**
* Constructor.
@@ -52,12 +50,58 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
*/
public ArrayStaticIntegerDBIDs(int... ids) {
super();
- this.ids = ids;
+ this.store = ids;
+ }
+
+ @Override
+ public int size() {
+ return store.length;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return store.length == 0;
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ final int oid = DBIDUtil.asInteger(o);
+ for (int i = 0; i < store.length; i++) {
+ if (store[i] == oid) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public DBID get(int i) {
+ return DBIDFactory.FACTORY.importInteger(store[i]);
+ }
+
+ @Override
+ public void assignVar(int i, DBIDVar var) {
+ if (var instanceof IntegerDBIDVar) {
+ ((IntegerDBIDVar) var).internalSetIndex(store[i]);
+ } else {
+ // Much less efficient:
+ var.set(get(i));
+ }
+ }
+
+ @Override
+ public int binarySearch(DBIDRef key) {
+ return Arrays.binarySearch(store, DBIDUtil.asInteger(key));
}
@Override
- public IntegerDBIDArrayIter iter() {
- return new DBIDItr();
+ public Itr iter() {
+ return new Itr();
+ }
+
+ @Override
+ public Slice slice(int begin, int end) {
+ return new Slice(begin, end);
}
/**
@@ -67,7 +111,7 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
*
* @apiviz.exclude
*/
- protected class DBIDItr implements IntegerDBIDArrayIter {
+ protected class Itr implements IntegerDBIDArrayIter {
/**
* Position within array.
*/
@@ -75,7 +119,7 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
@Override
public boolean valid() {
- return pos < ids.length && pos >= 0;
+ return pos < store.length && pos >= 0;
}
@Override
@@ -105,12 +149,12 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
@Override
public int internalGetIndex() {
- return ids[pos];
+ return store[pos];
}
@Override
public boolean equals(Object other) {
- if(other instanceof DBID) {
+ if (other instanceof DBID) {
LoggingUtil.warning("Programming error detected: DBIDItr.equals(DBID). Use sameDBID()!", new Throwable());
}
return super.equals(other);
@@ -122,44 +166,130 @@ public class ArrayStaticIntegerDBIDs implements IntegerArrayStaticDBIDs {
}
}
- @Override
- public int size() {
- return ids.length;
- }
+ /**
+ * Slice of an array.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class Slice implements IntegerArrayDBIDs {
+ /**
+ * Slice positions.
+ */
+ final int begin, end;
- @Override
- public boolean isEmpty() {
- return ids.length == 0;
- }
+ /**
+ * Constructor.
+ *
+ * @param begin Begin, inclusive
+ * @param end End, exclusive
+ */
+ public Slice(int begin, int end) {
+ super();
+ this.begin = begin;
+ this.end = end;
+ }
- @Override
- public boolean contains(DBIDRef o) {
- final int oid = DBIDUtil.asInteger(o);
- for(int i = 0; i < ids.length; i++) {
- if(ids[i] == oid) {
- return true;
+ @Override
+ public int size() {
+ return end - begin;
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ // TODO: recognize sorted arrays, then use binary search?
+ int oid = o.internalGetIndex();
+ for (int i = begin; i < end; i++) {
+ if (store[i] == oid) {
+ return true;
+ }
}
+ return false;
}
- return false;
- }
- @Override
- public DBID get(int i) {
- return DBIDFactory.FACTORY.importInteger(ids[i]);
- }
+ @Override
+ public boolean isEmpty() {
+ return begin == end;
+ }
- @Override
- public void assignVar(int i, DBIDVar var) {
- if (var instanceof IntegerDBIDVar) {
- ((IntegerDBIDVar)var).internalSetIndex(ids[i]);
- } else {
- // Much less efficient:
- var.set(get(i));
+ @Override
+ public DBID get(int i) {
+ return ArrayStaticIntegerDBIDs.this.get(begin + i);
}
- }
- @Override
- public int binarySearch(DBIDRef key) {
- return Arrays.binarySearch(ids, DBIDUtil.asInteger(key));
+ @Override
+ public void assignVar(int index, DBIDVar var) {
+ ArrayStaticIntegerDBIDs.this.assignVar(begin + index, var);
+ }
+
+ @Override
+ public int binarySearch(DBIDRef key) {
+ return Arrays.binarySearch(store, begin, end, key.internalGetIndex()) - begin;
+ }
+
+ @Override
+ public SliceItr iter() {
+ return new SliceItr();
+ }
+
+ @Override
+ public Slice slice(int begin, int end) {
+ return new Slice(begin + begin, begin + end);
+ }
+
+ /**
+ * Iterator class.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class SliceItr implements IntegerDBIDArrayIter {
+ /**
+ * Iterator position.
+ */
+ int pos = begin;
+
+ @Override
+ public int internalGetIndex() {
+ return store[pos];
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < end && pos >= begin;
+ }
+
+ @Override
+ public void advance() {
+ ++pos;
+ }
+
+ @Override
+ public int getOffset() {
+ return pos;
+ }
+
+ @Override
+ public void advance(int count) {
+ pos += count;
+ }
+
+ @Override
+ public void retract() {
+ --pos;
+ }
+
+ @Override
+ public void seek(int off) {
+ pos = begin + off;
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(internalGetIndex()) + "@" + pos;
+ }
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java
index 6c88c2d8..96babaa3 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNHeap.java
@@ -90,7 +90,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
@Override
@Deprecated
public DoubleDistance getKNNDistance() {
- if (heap.size() < k) {
+ if(heap.size() < k) {
return DoubleDistance.INFINITE_DISTANCE;
}
return new DoubleDistance(kdist);
@@ -103,41 +103,92 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
@Override
@Deprecated
- public void add(DoubleDistance distance, DBIDRef id) {
- add(distance.doubleValue(), id);
+ public void insert(DoubleDistance distance, DBIDRef id) {
+ final double dist = distance.doubleValue();
+ final int iid = id.internalGetIndex();
+ if(heap.size() < k) {
+ heap.add(dist, iid);
+ if(heap.size() >= k) {
+ kdist = heap.peekKey();
+ }
+ return;
+ }
+ // Tied with top:
+ if(dist >= kdist) {
+ if(dist == kdist) {
+ addToTies(iid);
+ }
+ return;
+ }
+ // Old top element: (kdist, previd)
+ updateHeap(dist, iid);
}
@Override
@Deprecated
- public void add(Double distance, DBIDRef id) {
- add(distance.doubleValue(), id);
+ public void insert(Double distance, DBIDRef id) {
+ final double dist = distance.doubleValue();
+ final int iid = id.internalGetIndex();
+ if(heap.size() < k) {
+ heap.add(dist, iid);
+ if(heap.size() >= k) {
+ kdist = heap.peekKey();
+ }
+ return;
+ }
+ // Tied with top:
+ if(dist >= kdist) {
+ if(dist == kdist) {
+ addToTies(iid);
+ }
+ return;
+ }
+ // Old top element: (kdist, previd)
+ updateHeap(dist, iid);
}
@Override
- public final void add(final double distance, final DBIDRef id) {
- if (distance > kdist) {
- return;
- }
+ public final double insert(final double distance, final DBIDRef id) {
final int iid = id.internalGetIndex();
- if (heap.size() < k) {
+ if(heap.size() < k) {
heap.add(distance, iid);
- if (heap.size() >= k) {
+ if(heap.size() >= k) {
kdist = heap.peekKey();
}
- return;
+ return kdist;
}
// Tied with top:
- if (distance >= kdist) {
- addToTies(iid);
- return;
+ if(distance >= kdist) {
+ if(distance == kdist) {
+ addToTies(iid);
+ }
+ return kdist;
}
// Old top element: (kdist, previd)
updateHeap(distance, iid);
+ return kdist;
}
@Override
- public void add(DoubleDistanceDBIDPair e) {
- add(e.doubleDistance(), e);
+ public void insert(final DoubleDistanceDBIDPair e) {
+ final double distance = e.doubleDistance();
+ final int iid = e.internalGetIndex();
+ if(heap.size() < k) {
+ heap.add(distance, iid);
+ if(heap.size() >= k) {
+ kdist = heap.peekKey();
+ }
+ return;
+ }
+ // Tied with top:
+ if(distance >= kdist) {
+ if(distance == kdist) {
+ addToTies(iid);
+ }
+ return;
+ }
+ // Old top element: (kdist, previd)
+ updateHeap(distance, iid);
}
/**
@@ -152,9 +203,10 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
heap.replaceTopElement(distance, iid);
kdist = heap.peekKey();
// If the kdist improved, zap ties.
- if (kdist < prevdist) {
+ if(kdist < prevdist) {
numties = 0;
- } else {
+ }
+ else {
addToTies(previd);
}
}
@@ -165,7 +217,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
* @param id Id to add
*/
private final void addToTies(int id) {
- if (ties.length == numties) {
+ if(ties.length == numties) {
ties = Arrays.copyOf(ties, (ties.length << 1) + 1); // grow.
}
ties[numties] = id;
@@ -175,10 +227,11 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
@Override
public DoubleDistanceIntegerDBIDPair poll() {
final DoubleDistanceIntegerDBIDPair ret;
- if (numties > 0) {
+ if(numties > 0) {
ret = new DoubleDistanceIntegerDBIDPair(kdist, ties[numties - 1]);
--numties;
- } else {
+ }
+ else {
ret = new DoubleDistanceIntegerDBIDPair(heap.peekKey(), heap.peekValue());
heap.poll();
}
@@ -189,16 +242,17 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
* Pop the topmost element.
*/
protected void pop() {
- if (numties > 0) {
+ if(numties > 0) {
--numties;
- } else {
+ }
+ else {
heap.poll();
}
}
@Override
public DoubleDistanceIntegerDBIDPair peek() {
- if (numties > 0) {
+ if(numties > 0) {
return new DoubleDistanceIntegerDBIDPair(kdist, ties[numties - 1]);
}
return new DoubleDistanceIntegerDBIDPair(heap.peekKey(), heap.peekValue());
@@ -222,7 +276,21 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
@Override
public DoubleDistanceIntegerDBIDKNNList toKNNList() {
- return new DoubleDistanceIntegerDBIDKNNList(this);
+ final int hsize = heap.size();
+ DoubleDistanceIntegerDBIDKNNList ret = new DoubleDistanceIntegerDBIDKNNList(k, hsize + numties);
+ // Add ties:
+ for(int i = 0; i < numties; i++) {
+ ret.dists[hsize + i] = kdist;
+ ret.ids[hsize + i] = ties[i];
+ }
+ for(int j = hsize - 1; j >= 0; j--) {
+ ret.dists[j] = heap.peekKey();
+ ret.ids[j] = heap.peekValue();
+ heap.poll();
+ }
+ ret.size = hsize + numties;
+ ret.sort();
+ return ret;
}
/**
@@ -231,9 +299,10 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
* @return distance
*/
protected double peekDistance() {
- if (numties > 0) {
+ if(numties > 0) {
return kdist;
- } else {
+ }
+ else {
return heap.peekKey();
}
}
@@ -244,7 +313,7 @@ public class DoubleDistanceIntegerDBIDKNNHeap implements DoubleDistanceKNNHeap {
* @return internal id
*/
protected int peekInternalDBID() {
- if (numties > 0) {
+ if(numties > 0) {
return ties[numties - 1];
}
return heap.peekValue();
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java
index a74497e8..f6515d88 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNList.java
@@ -22,47 +22,21 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Arrays;
-
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
-import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
- * Class to store double distance, integer DBID results.
+ * kNN list, but without automatic sorting. Use with care, as others may expect
+ * the results to be sorted!
*
* @author Erich Schubert
- *
- * @apiviz.uses DoubleIntegerArrayQuickSort
*/
-public class DoubleDistanceIntegerDBIDKNNList implements ModifiableDoubleDistanceDBIDList, DoubleDistanceKNNList, IntegerDBIDs {
- /**
- * Initial size allocation.
- */
- private static final int INITIAL_SIZE = 21;
-
+public class DoubleDistanceIntegerDBIDKNNList extends DoubleDistanceIntegerDBIDList implements DoubleDistanceKNNList {
/**
* The k value this list was generated for.
*/
- int k;
-
- /**
- * The size
- */
- int size;
-
- /**
- * Distance values
- */
- double[] dists;
-
- /**
- * DBIDs
- */
- int[] ids;
+ final int k;
/**
* Constructor.
@@ -70,8 +44,6 @@ public class DoubleDistanceIntegerDBIDKNNList implements ModifiableDoubleDistanc
public DoubleDistanceIntegerDBIDKNNList() {
super();
this.k = -1;
- this.dists = new double[INITIAL_SIZE];
- this.ids = new int[INITIAL_SIZE];
}
/**
@@ -80,75 +52,20 @@ public class DoubleDistanceIntegerDBIDKNNList implements ModifiableDoubleDistanc
* @param k K parameter
* @param size Actual size
*/
- public DoubleDistanceIntegerDBIDKNNList(int k, int size) {
- super();
+ public DoubleDistanceIntegerDBIDKNNList(final int k, int size) {
+ super(size);
this.k = k;
- if (size > 0) {
- this.dists = new double[size];
- this.ids = new int[size];
- } else {
- this.dists = new double[INITIAL_SIZE];
- this.ids = new int[INITIAL_SIZE];
- }
- }
-
- /**
- * Constructor from heap.
- *
- * @param heap KNN heap.
- */
- public DoubleDistanceIntegerDBIDKNNList(DoubleDistanceIntegerDBIDKNNHeap heap) {
- super();
- this.k = heap.getK();
- this.size = heap.size();
- this.dists = new double[size];
- this.ids = new int[size];
- for (int i = size - 1; i >= 0; i--) {
- dists[i] = heap.peekDistance();
- ids[i] = heap.peekInternalDBID();
- heap.pop();
- }
- }
-
- @Override
- public DoubleDistanceIntegerDBIDListIter iter() {
- return new Itr();
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- final int q = o.internalGetIndex();
- for (int i = 0; i < size; i++) {
- if (q == ids[i]) {
- return true;
- }
- }
- return false;
- }
-
- @Override
- public boolean isEmpty() {
- return size == 0;
- }
-
- @Override
- public int size() {
- return size;
}
@Override
public int getK() {
- if (k <= 0) {
- return size - 1;
- }
return k;
}
- @Override
- public DoubleDistanceIntegerDBIDPair get(int index) {
- return new DoubleDistanceIntegerDBIDPair(dists[index], ids[index]);
- }
-
+ /**
+ * @deprecated Since you know this is a double distance heap, use
+ * {@link #doubleKNNDistance()}
+ */
@Override
@Deprecated
public DoubleDistance getKNNDistance() {
@@ -157,65 +74,7 @@ public class DoubleDistanceIntegerDBIDKNNList implements ModifiableDoubleDistanc
@Override
public double doubleKNNDistance() {
- if (k <= 0) {
- return dists[size - 1];
- }
- if (size < k) {
- return Double.POSITIVE_INFINITY;
- }
- return dists[k - 1];
- }
-
- /**
- * Add an entry, consisting of distance and internal index.
- *
- * @param dist Distance
- * @param id Internal index
- */
- protected void add(double dist, int id) {
- if (size == dists.length) {
- final int newlength = (dists.length << 1) + 1;
- dists = Arrays.copyOf(dists, newlength);
- ids = Arrays.copyOf(ids, newlength);
- }
- dists[size] = dist;
- ids[size] = id;
- ++size;
- }
-
- @Override
- @Deprecated
- public void add(DoubleDistance dist, DBIDRef id) {
- add(dist.doubleValue(), id);
- }
-
- @Override
- public void add(double dist, DBIDRef id) {
- add(dist, id.internalGetIndex());
- }
-
- @Override
- public void add(DoubleDistanceDBIDPair pair) {
- add(pair.doubleDistance(), pair.internalGetIndex());
- }
-
- @Override
- public void sort() {
- DoubleIntegerArrayQuickSort.sort(dists, ids, 0, size);
- }
-
- /**
- * Reverse the list.
- */
- protected void reverse() {
- for (int i = 0, j = size - 1; i < j; i++, j--) {
- double tmpd = dists[j];
- dists[j] = dists[i];
- dists[i] = tmpd;
- int tmpi = ids[j];
- ids[j] = ids[i];
- ids[i] = tmpi;
- }
+ return (size >= k) ? dists[k - 1] : Double.POSITIVE_INFINITY;
}
@Override
@@ -232,67 +91,4 @@ public class DoubleDistanceIntegerDBIDKNNList implements ModifiableDoubleDistanc
buf.append(']');
return buf.toString();
}
-
- /**
- * List iterator.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- private class Itr implements DoubleDistanceIntegerDBIDListIter {
- int offset = 0;
-
- @Override
- public boolean valid() {
- return offset < size;
- }
-
- @Override
- public void advance() {
- ++offset;
- }
-
- @Override
- public int getOffset() {
- return offset;
- }
-
- @Override
- public void advance(int count) {
- offset += count;
- }
-
- @Override
- public void retract() {
- offset--;
- }
-
- @Override
- public void seek(int off) {
- offset = off;
- }
-
- @Override
- public int internalGetIndex() {
- return ids[offset];
- }
-
- @Override
- public double doubleDistance() {
- return dists[offset];
- }
-
- @Override
- public DoubleDistanceDBIDPair getDistancePair() {
- return new DoubleDistanceIntegerDBIDPair(dists[offset], ids[offset]);
- }
-
- @Override
- @Deprecated
- public DoubleDistance getDistance() {
- return new DoubleDistance(dists[offset]);
- }
-
- }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java
index ffc2266e..0db0204c 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDKNNListHeap.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDList.java
@@ -22,13 +22,11 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-import java.util.Arrays;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
-import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
+import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
/**
@@ -38,11 +36,11 @@ import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
*
* @apiviz.uses DoubleIntegerArrayQuickSort
*/
-public class DoubleDistanceIntegerDBIDKNNListHeap implements DoubleDistanceKNNHeap, DoubleDistanceKNNList, IntegerDBIDs {
+public class DoubleDistanceIntegerDBIDList implements ModifiableDoubleDistanceDBIDList, IntegerDBIDs {
/**
- * The k value this list was generated for.
+ * Initial size allocation.
*/
- int k;
+ private static final int INITIAL_SIZE = 21;
/**
* The size
@@ -60,28 +58,44 @@ public class DoubleDistanceIntegerDBIDKNNListHeap implements DoubleDistanceKNNHe
int[] ids;
/**
+ * Empty.
+ */
+ private static final double[] EMPTY_DISTS = new double[0];
+
+ /**
+ * Empty.
+ */
+ private static final int[] EMPTY_IDS = new int[0];
+
+ /**
+ * Constructor.
+ */
+ public DoubleDistanceIntegerDBIDList() {
+ dists = EMPTY_DISTS;
+ ids = EMPTY_IDS;
+ }
+
+ /**
* Constructor.
*
- * @param k K parameter
+ * @param size Initial size
*/
- public DoubleDistanceIntegerDBIDKNNListHeap(int k) {
- super();
- this.k = k;
- this.size = 0;
- this.dists = new double[k + 1];
- this.ids = new int[k + 1];
+ public DoubleDistanceIntegerDBIDList(int size) {
+ this.dists = new double[size];
+ this.ids = new int[size];
+ // This is default anyway: this.size = 0;
}
@Override
- public DoubleDistanceIntegerDBIDListIter iter() {
+ public Itr iter() {
return new Itr();
}
@Override
public boolean contains(DBIDRef o) {
final int q = o.internalGetIndex();
- for(int i = 0; i < size; i++) {
- if(q == ids[i]) {
+ for (int i = 0; i < size; i++) {
+ if (q == ids[i]) {
return true;
}
}
@@ -99,151 +113,123 @@ public class DoubleDistanceIntegerDBIDKNNListHeap implements DoubleDistanceKNNHe
}
@Override
- public int getK() {
- return k;
- }
-
- @Override
public DoubleDistanceIntegerDBIDPair get(int index) {
return new DoubleDistanceIntegerDBIDPair(dists[index], ids[index]);
}
- @Override
- @Deprecated
- public DoubleDistance getKNNDistance() {
- return new DoubleDistance(doubleKNNDistance());
- }
-
- @Override
- public double doubleKNNDistance() {
- if(size < k) {
- return Double.POSITIVE_INFINITY;
- }
- return dists[k - 1];
- }
-
/**
* Add an entry, consisting of distance and internal index.
*
* @param dist Distance
* @param id Internal index
*/
- protected void append(double dist, int id) {
- ensureSize(size + 1);
+ protected void addInternal(double dist, int id) {
+ if (size == dists.length) {
+ grow();
+ }
dists[size] = dist;
ids[size] = id;
++size;
}
/**
- * Add a new element to the heap/list.
- *
- * @param dist Distance
- * @param id Object ID
+ * Grow the data storage.
*/
- protected void add(double dist, int id) {
- if(size < k) {
- dists[size] = dist;
- ids[size] = id;
- ++size;
- if(size == k) {
- sort();
- }
- return;
- }
- if (dist > dists[size - 1]) {
+ protected void grow() {
+ if (dists == EMPTY_DISTS) {
+ dists = new double[INITIAL_SIZE];
+ ids = new int[INITIAL_SIZE];
return;
}
- // Ensure we have enough space.
- ensureSize(size + 1);
- // Insertion sort:
- int pos = size;
- while(pos > 0 && dists[pos - 1] > dist) {
- dists[pos] = dists[pos - 1];
- ids[pos] = ids[pos - 1];
- --pos;
- }
- dists[pos] = dist;
- ids[pos] = id;
- ++size;
- // Truncate if necessary:
- if(dists[k] > dists[k - 1]) {
- size = k;
- }
- }
-
- /**
- * Ensure we have enough space.
- *
- * @param size Desired size
- */
- private void ensureSize(int size) {
- if(size > dists.length) {
- final int newlength = Math.max(size, (dists.length << 1) + 1);
- dists = Arrays.copyOf(dists, newlength);
- ids = Arrays.copyOf(ids, newlength);
- }
+ final int len = dists.length;
+ final int newlength = len + (len >> 1);
+ double[] odists = dists;
+ dists = new double[newlength];
+ System.arraycopy(odists, 0, dists, 0, odists.length);
+ int[] oids = ids;
+ ids = new int[newlength];
+ System.arraycopy(oids, 0, ids, 0, oids.length);
}
@Override
@Deprecated
public void add(DoubleDistance dist, DBIDRef id) {
- add(dist.doubleValue(), id);
- }
-
- @Override
- @Deprecated
- public void add(Double dist, DBIDRef id) {
- add(dist.doubleValue(), id);
+ addInternal(dist.doubleValue(), id.internalGetIndex());
}
@Override
public void add(double dist, DBIDRef id) {
- add(dist, id.internalGetIndex());
+ addInternal(dist, id.internalGetIndex());
}
@Override
public void add(DoubleDistanceDBIDPair pair) {
- add(pair.doubleDistance(), pair.internalGetIndex());
- }
-
- /**
- * Sort the current contents of the list.
- */
- protected void sort() {
- DoubleIntegerArrayQuickSort.sort(dists, ids, 0, size);
+ addInternal(pair.doubleDistance(), pair.internalGetIndex());
}
@Override
public void clear() {
size = 0;
- Arrays.fill(dists, Double.NaN);
- Arrays.fill(ids, -1);
+ // TODO: put NaN/-1 everywhere, or don't care?
}
@Override
- public DoubleDistanceIntegerDBIDPair poll() {
- return new DoubleDistanceIntegerDBIDPair(dists[k], ids[k]);
+ public void sort() {
+ DoubleIntegerArrayQuickSort.sort(dists, ids, 0, size);
}
- @Override
- public DoubleDistanceIntegerDBIDPair peek() {
- return new DoubleDistanceIntegerDBIDPair(dists[k], ids[k]);
+ /**
+ * Reverse the list.
+ */
+ protected void reverse() {
+ for (int i = 0, j = size - 1; i < j; i++, j--) {
+ double tmpd = dists[j];
+ dists[j] = dists[i];
+ dists[i] = tmpd;
+ int tmpi = ids[j];
+ ids[j] = ids[i];
+ ids[i] = tmpi;
+ }
}
- @Override
- public DoubleDistanceKNNList toKNNList() {
- return this;
+ /**
+ * Truncate the list to the given size.
+ *
+ * @param newsize New size
+ */
+ public void truncate(int newsize) {
+ if (newsize < size) {
+ double[] odists = dists;
+ dists = new double[newsize];
+ System.arraycopy(odists, 0, dists, 0, newsize);
+ int[] oids = ids;
+ ids = new int[newsize];
+ System.arraycopy(oids, 0, ids, 0, newsize);
+ size = newsize;
+ }
+ }
+
+ /**
+ * Get the distance of the object at position pos.
+ *
+ * Usually, you should be using an iterator instead. This part of the API is
+ * not stable.
+ *
+ * @param pos Position
+ * @return Double distance.
+ */
+ public double getDoubleDistance(int pos) {
+ return dists[pos];
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder();
- buf.append("kNNListHeap[");
- for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append("DistanceDBIDList[");
+ for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
iter.advance();
- if(iter.valid()) {
+ if (iter.valid()) {
buf.append(',');
}
}
@@ -259,8 +245,18 @@ public class DoubleDistanceIntegerDBIDKNNListHeap implements DoubleDistanceKNNHe
* @apiviz.exclude
*/
private class Itr implements DoubleDistanceIntegerDBIDListIter {
+ /**
+ * Current offset.
+ */
int offset = 0;
+ /**
+ * Constructor.
+ */
+ private Itr() {
+ super();
+ }
+
@Override
public boolean valid() {
return offset < size;
@@ -283,7 +279,7 @@ public class DoubleDistanceIntegerDBIDKNNListHeap implements DoubleDistanceKNNHe
@Override
public void retract() {
- offset--;
+ --offset;
}
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java
new file mode 100644
index 00000000..aa0a9739
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairKNNListHeap.java
@@ -0,0 +1,339 @@
+package de.lmu.ifi.dbs.elki.database.ids.integer;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+
+/**
+ * Finalized KNN List.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.composedOf DoubleDistanceDBIDPair
+ * @apiviz.has DoubleDistanceDBIDListIter
+ */
+public class DoubleDistanceIntegerDBIDPairKNNListHeap implements DoubleDistanceKNNList, DoubleDistanceKNNHeap {
+ /**
+ * The value of k this was materialized for.
+ */
+ private final int k;
+
+ /**
+ * The actual data array.
+ */
+ private DoubleDistanceIntegerDBIDPair[] data;
+
+ /**
+ * Current size
+ */
+ private int size;
+
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ */
+ public DoubleDistanceIntegerDBIDPairKNNListHeap(int k) {
+ super();
+ this.data = new DoubleDistanceIntegerDBIDPair[k + 5];
+ this.k = k;
+ this.size = 0;
+ }
+
+ @Override
+ public void clear() {
+ for(int i = 0; i < size; i++) {
+ data[i] = null; // discard
+ }
+ size = 0;
+ }
+
+ @Override
+ public double insert(double distance, DBIDRef id) {
+ final int kminus1 = k - 1;
+ if(size < k || distance <= data[kminus1].doubleDistance()) {
+ // Ensure we have enough space.
+ if(size > data.length) {
+ grow();
+ }
+ insertionSort(new DoubleDistanceIntegerDBIDPair(distance, id.internalGetIndex()));
+ // Truncate if necessary:
+ if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
+ truncate();
+ }
+ }
+ return (size < k) ? Double.POSITIVE_INFINITY : get(kminus1).doubleDistance();
+ }
+
+ private void truncate() {
+ for(int i = k; i < size; i++) {
+ data[i] = null; // discard
+ }
+ size = k;
+ }
+
+ @Override
+ @Deprecated
+ public void insert(Double distance, DBIDRef id) {
+ final int kminus1 = k - 1;
+ if(size < k || distance.doubleValue() <= data[kminus1].doubleDistance()) {
+ // Ensure we have enough space.
+ if(size > data.length) {
+ grow();
+ }
+ insertionSort(new DoubleDistanceIntegerDBIDPair(distance.doubleValue(), id.internalGetIndex()));
+ // Truncate if necessary:
+ if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
+ truncate();
+ }
+ }
+ }
+
+ @Override
+ @Deprecated
+ public void insert(DoubleDistance dist, DBIDRef id) {
+ final int kminus1 = k - 1;
+ if(size < k || dist.doubleValue() <= data[kminus1].doubleDistance()) {
+ // Ensure we have enough space.
+ if(size > data.length) {
+ grow();
+ }
+ insertionSort(new DoubleDistanceIntegerDBIDPair(dist.doubleValue(), id.internalGetIndex()));
+ // Truncate if necessary:
+ if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
+ truncate();
+ }
+ }
+ }
+
+ @Override
+ public void insert(DoubleDistanceDBIDPair e) {
+ final int kminus1 = k - 1;
+ final double dist = e.doubleDistance();
+ if(size < k || dist <= data[kminus1].doubleDistance()) {
+ // Ensure we have enough space.
+ if(size > data.length) {
+ grow();
+ }
+ if(e instanceof DoubleDistanceIntegerDBIDPair) {
+ insertionSort((DoubleDistanceIntegerDBIDPair) e);
+ }
+ else {
+ insertionSort(new DoubleDistanceIntegerDBIDPair(dist, e.internalGetIndex()));
+ }
+ // Truncate if necessary:
+ if(size > k && data[k].doubleDistance() > data[kminus1].doubleDistance()) {
+ truncate();
+ }
+ }
+ }
+
+ /**
+ * Perform insertion sort.
+ *
+ * @param obj Object to insert
+ */
+ private void insertionSort(DoubleDistanceIntegerDBIDPair obj) {
+ // Insertion sort:
+ int pos = size;
+ while(pos > 0) {
+ final int prev = pos - 1;
+ DoubleDistanceIntegerDBIDPair pobj = data[prev];
+ if(pobj.doubleDistance() <= obj.doubleDistance()) {
+ break;
+ }
+ data[pos] = pobj;
+ pos = prev;
+ }
+ data[pos] = obj;
+ ++size;
+ }
+
+ private void grow() {
+ final DoubleDistanceIntegerDBIDPair[] old = data;
+ data = new DoubleDistanceIntegerDBIDPair[data.length + (data.length >> 1)];
+ System.arraycopy(old, 0, data, 0, old.length);
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair poll() {
+ assert (size > 0);
+ return data[size--];
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair peek() {
+ assert (size > 0);
+ return data[size - 1];
+ }
+
+ @Override
+ public DoubleDistanceKNNList toKNNList() {
+ return this;
+ }
+
+ @Override
+ public int getK() {
+ return k;
+ }
+
+ @Override
+ @Deprecated
+ public DoubleDistance getKNNDistance() {
+ if(size < k) {
+ return DoubleDistance.INFINITE_DISTANCE;
+ }
+ return get(k - 1).getDistance();
+ }
+
+ @Override
+ public double doubleKNNDistance() {
+ if(size < k) {
+ return Double.POSITIVE_INFINITY;
+ }
+ return get(k - 1).doubleDistance();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("kNNList[");
+ for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleDistance()).append(':').append(DBIDUtil.toString(iter));
+ iter.advance();
+ if(iter.valid()) {
+ buf.append(',');
+ }
+ }
+ buf.append(']');
+ return buf.toString();
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair get(int index) {
+ return data[index];
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDListIter iter() {
+ return new Itr();
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
+ if(DBIDUtil.equal(iter, o)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ /**
+ * Iterator.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class Itr implements DoubleDistanceIntegerDBIDListIter {
+ /**
+ * Cursor position.
+ */
+ private int pos = 0;
+
+ @Override
+ public int internalGetIndex() {
+ return get(pos).internalGetIndex();
+ }
+
+ @Override
+ public boolean valid() {
+ return pos < size;
+ }
+
+ @Override
+ public void advance() {
+ pos++;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @deprecated use {@link #doubleDistance}!
+ */
+ @Override
+ @Deprecated
+ public DoubleDistance getDistance() {
+ return get(pos).getDistance();
+ }
+
+ @Override
+ public double doubleDistance() {
+ return get(pos).doubleDistance();
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair getDistancePair() {
+ return get(pos);
+ }
+
+ @Override
+ public int getOffset() {
+ return pos;
+ }
+
+ @Override
+ public void advance(int count) {
+ pos += count;
+ }
+
+ @Override
+ public void retract() {
+ --pos;
+ }
+
+ @Override
+ public void seek(int off) {
+ pos = off;
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java
new file mode 100644
index 00000000..5b33d3f9
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDPairList.java
@@ -0,0 +1,234 @@
+package de.lmu.ifi.dbs.elki.database.ids.integer;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import java.util.Arrays;
+
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.distance.ModifiableDoubleDistanceDBIDList;
+import de.lmu.ifi.dbs.elki.distance.distanceresultlist.DistanceDBIDResultUtil;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+
+/**
+ * Class to store double distance, integer DBID results.
+ *
+ * @author Erich Schubert
+ */
+public class DoubleDistanceIntegerDBIDPairList implements ModifiableDoubleDistanceDBIDList, IntegerDBIDs {
+ /**
+ * The size
+ */
+ int size;
+
+ /**
+ * Distance values
+ */
+ DoubleDistanceIntegerDBIDPair[] data;
+
+ /**
+ * Constructor.
+ */
+ public DoubleDistanceIntegerDBIDPairList() {
+ super();
+ this.data = new DoubleDistanceIntegerDBIDPair[21];
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param size Initial size
+ */
+ public DoubleDistanceIntegerDBIDPairList(int size) {
+ super();
+ if (size > 0) {
+ size = 21;
+ }
+ this.data = new DoubleDistanceIntegerDBIDPair[size];
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDListIter iter() {
+ return new Itr();
+ }
+
+ @Override
+ public boolean contains(DBIDRef o) {
+ final int q = o.internalGetIndex();
+ for (int i = 0; i < size; i++) {
+ if (q == data[i].internalGetIndex()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ @Override
+ public int size() {
+ return size;
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair get(int index) {
+ return data[index];
+ }
+
+ /**
+ * Add an entry, consisting of distance and internal index.
+ *
+ * @param pair entry
+ */
+ protected void addInternal(DoubleDistanceIntegerDBIDPair pair) {
+ if (size == data.length) {
+ DoubleDistanceIntegerDBIDPair[] old = data;
+ data = new DoubleDistanceIntegerDBIDPair[(data.length << 1) + 1];
+ System.arraycopy(old, 0, data, 0, old.length);
+ }
+ data[size++] = pair;
+ }
+
+ @Override
+ @Deprecated
+ public void add(DoubleDistance dist, DBIDRef id) {
+ add(dist.doubleValue(), id);
+ }
+
+ @Override
+ public void add(double dist, DBIDRef id) {
+ addInternal(new DoubleDistanceIntegerDBIDPair(dist, id.internalGetIndex()));
+ }
+
+ @Override
+ public void add(DoubleDistanceDBIDPair pair) {
+ if (pair instanceof DoubleDistanceIntegerDBIDPair) {
+ addInternal((DoubleDistanceIntegerDBIDPair) pair);
+ } else {
+ addInternal(new DoubleDistanceIntegerDBIDPair(pair.doubleDistance(), pair.internalGetIndex()));
+ }
+ }
+
+ @Override
+ public void clear() {
+ Arrays.fill(data, null);
+ size = 0;
+ }
+
+ @Override
+ public void sort() {
+ Arrays.sort(data, 0, size, DistanceDBIDResultUtil.distanceComparator());
+ }
+
+ /**
+ * Reverse the list.
+ */
+ protected void reverse() {
+ for (int i = 0, j = size - 1; i < j; i++, j--) {
+ DoubleDistanceIntegerDBIDPair tmpd = data[j];
+ data[j] = data[i];
+ data[i] = tmpd;
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("kNNList[");
+ for (DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
+ iter.advance();
+ if (iter.valid()) {
+ buf.append(',');
+ }
+ }
+ buf.append(']');
+ return buf.toString();
+ }
+
+ /**
+ * List iterator.
+ *
+ * @author Erich Schubert
+ *
+ * @apiviz.exclude
+ */
+ private class Itr implements DoubleDistanceIntegerDBIDListIter {
+ int offset = 0;
+
+ @Override
+ public boolean valid() {
+ return offset < size;
+ }
+
+ @Override
+ public void advance() {
+ ++offset;
+ }
+
+ @Override
+ public int getOffset() {
+ return offset;
+ }
+
+ @Override
+ public void advance(int count) {
+ offset += count;
+ }
+
+ @Override
+ public void retract() {
+ offset--;
+ }
+
+ @Override
+ public void seek(int off) {
+ offset = off;
+ }
+
+ @Override
+ public int internalGetIndex() {
+ return data[offset].internalGetIndex();
+ }
+
+ @Override
+ public double doubleDistance() {
+ return data[offset].doubleDistance();
+ }
+
+ @Override
+ public DoubleDistanceDBIDPair getDistancePair() {
+ return data[offset];
+ }
+
+ @Override
+ @Deprecated
+ public DoubleDistance getDistance() {
+ return new DoubleDistance(data[offset].doubleDistance());
+ }
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java
new file mode 100644
index 00000000..c4c60bc0
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/DoubleDistanceIntegerDBIDSortedKNNList.java
@@ -0,0 +1,157 @@
+package de.lmu.ifi.dbs.elki.database.ids.integer;
+
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2013
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDListIter;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceDBIDPair;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNHeap;
+import de.lmu.ifi.dbs.elki.database.ids.distance.DoubleDistanceKNNList;
+import de.lmu.ifi.dbs.elki.distance.distancevalue.DoubleDistance;
+
+/**
+ * Track the k nearest neighbors, with insertion sort to ensure the correct
+ * order.
+ *
+ * @author Erich Schubert
+ */
+public class DoubleDistanceIntegerDBIDSortedKNNList extends DoubleDistanceIntegerDBIDKNNList implements DoubleDistanceKNNHeap {
+ /**
+ * Constructor.
+ *
+ * @param k K parameter
+ */
+ public DoubleDistanceIntegerDBIDSortedKNNList(int k) {
+ super(k, k + 11);
+ }
+
+ /**
+ * Add a new element to the heap/list.
+ *
+ * @param dist Distance
+ * @param id Object ID
+ */
+ @Override
+ protected final void addInternal(final double dist, final int id) {
+ if(size >= k && dist > dists[k - 1]) {
+ return;
+ }
+ insertionSort(dist, id);
+ }
+
+ /**
+ * Insertion sort a single object.
+ *
+ * @param dist New distance
+ * @param id New id
+ */
+ private void insertionSort(final double dist, final int id) {
+ // Ensure we have enough space.
+ if(size == dists.length) {
+ grow();
+ }
+ int pos = size;
+ while(pos > 0) {
+ final int pre = pos - 1;
+ final double predist = dists[pre];
+ if(predist <= dist) {
+ break;
+ }
+ dists[pos] = predist;
+ ids[pos] = ids[pre];
+ pos = pre;
+ }
+ dists[pos] = dist;
+ ids[pos] = id;
+ ++size;
+ if(size > k && dists[k] > dists[k - 1]) {
+ size = k; // truncate
+ }
+ return;
+ }
+
+ @Override
+ public double insert(double dist, DBIDRef id) {
+ final int kminus1 = k - 1;
+ final int iid = id.internalGetIndex();
+ if(size >= k && dist > dists[kminus1]) {
+ return (size >= k) ? dists[kminus1] : Double.POSITIVE_INFINITY;
+ }
+ insertionSort(dist, iid);
+ return (size >= k) ? dists[kminus1] : Double.POSITIVE_INFINITY;
+ }
+
+ @Override
+ public void add(double dist, DBIDRef id) {
+ addInternal(dist, id.internalGetIndex());
+ }
+
+ @Override
+ @Deprecated
+ public void insert(Double dist, DBIDRef id) {
+ addInternal(dist.doubleValue(), id.internalGetIndex());
+ }
+
+ @Override
+ public void insert(DoubleDistanceDBIDPair e) {
+ addInternal(e.doubleDistance(), e.internalGetIndex());
+ }
+
+ @Override
+ @Deprecated
+ public void insert(DoubleDistance dist, DBIDRef id) {
+ addInternal(dist.doubleValue(), id.internalGetIndex());
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair poll() {
+ final int last = size - 1;
+ return new DoubleDistanceIntegerDBIDPair(dists[last], ids[last]);
+ }
+
+ @Override
+ public DoubleDistanceIntegerDBIDPair peek() {
+ final int last = size - 1;
+ return new DoubleDistanceIntegerDBIDPair(dists[last], ids[last]);
+ }
+
+ @Override
+ public DoubleDistanceKNNList toKNNList() {
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder buf = new StringBuilder();
+ buf.append("kNNListHeap[");
+ for(DoubleDistanceDBIDListIter iter = this.iter(); iter.valid();) {
+ buf.append(iter.doubleDistance()).append(':').append(iter.internalGetIndex());
+ iter.advance();
+ if(iter.valid()) {
+ buf.append(',');
+ }
+ }
+ buf.append(']');
+ return buf.toString();
+ }
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java
index 61a12b3f..286bedf9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerArrayDBIDs.java
@@ -33,4 +33,7 @@ import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
public interface IntegerArrayDBIDs extends IntegerDBIDs, ArrayDBIDs {
@Override
IntegerDBIDArrayIter iter();
+
+ @Override
+ IntegerArrayDBIDs slice(int begin, int end);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java
index 40243695..6b7ec5ac 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBID.java
@@ -25,9 +25,11 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
import java.nio.ByteBuffer;
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
@@ -47,7 +49,6 @@ import de.lmu.ifi.dbs.elki.persistent.FixedSizeByteBufferSerializer;
*
* @author Erich Schubert
*
- * @apiviz.landmark
* @apiviz.composedOf DynamicSerializer
* @apiviz.composedOf StaticSerializer
*/
@@ -88,6 +89,16 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
}
@Override
+ public int size() {
+ return 1;
+ }
+
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ @Override
public String toString() {
return Integer.toString(id);
}
@@ -120,8 +131,8 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
}
@Override
- public DBIDArrayIter iter() {
- return new DBIDItr();
+ public Itr iter() {
+ return new Itr();
}
@Override
@@ -146,16 +157,20 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
}
@Override
- public int size() {
- return 1;
- }
-
- @Override
public int binarySearch(DBIDRef key) {
final int other = key.internalGetIndex();
return (other == id) ? 0 : (other < id) ? -1 : -2;
}
+ @Override
+ public ArrayDBIDs slice(int begin, int end) {
+ if (begin == 0 && end == 1) {
+ return this;
+ } else {
+ return DBIDUtil.EMPTYDBIDS;
+ }
+ }
+
/**
* Pseudo iterator for DBIDs interface.
*
@@ -163,7 +178,7 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
*
* @apiviz.exclude
*/
- protected class DBIDItr implements DBIDArrayIter, IntegerDBIDRef {
+ protected class Itr implements DBIDArrayIter, IntegerDBIDRef {
/**
* Iterator position: We use an integer so we can support retract().
*/
@@ -224,11 +239,6 @@ final class IntegerDBID implements DBID, IntegerDBIDRef {
}
}
- @Override
- public boolean isEmpty() {
- return false;
- }
-
/**
* Dynamic sized serializer, using varint.
*
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java
index 90a97609..d6cadf60 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDArrayQuickSort.java
@@ -42,7 +42,7 @@ import de.lmu.ifi.dbs.elki.utilities.documentation.Reference;
*
* @author Erich Schubert
*
- * @apiviz.uses TroveArrayModifiableDBIDs
+ * @apiviz.uses IntegerArrayDBIDs
*/
@Reference(authors = "Vladimir Yaroslavskiy", title = "Dual-Pivot Quicksort", booktitle = "http://iaroslavski.narod.ru/quicksort/", url = "http://iaroslavski.narod.ru/quicksort/")
class IntegerDBIDArrayQuickSort {
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java
index cc241475..721e6e4e 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDIter.java
@@ -28,6 +28,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
* Iterator for integer DBIDs.
*
* @author Erich Schubert
+ *
+ * @apiviz.landmark
*/
public interface IntegerDBIDIter extends IntegerDBIDRef, DBIDIter {
// Empty
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java
index 1b1ab154..12e9b685 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDPair.java
@@ -29,8 +29,6 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDPair;
* DBID pair using two ints for storage.
*
* @author Erich Schubert
- *
- * @apiviz.has IntegerDBID
*/
public class IntegerDBIDPair implements DBIDPair {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java
index 3ceb163d..e418db5f 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRange.java
@@ -23,22 +23,21 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDArrayIter;
import de.lmu.ifi.dbs.elki.database.ids.DBIDFactory;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRange;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
+import de.lmu.ifi.dbs.elki.database.ids.SetDBIDs;
/**
* Representing a DBID range allocation.
*
* @author Erich Schubert
- *
- * @apiviz.has IntegerDBID
*/
-class IntegerDBIDRange implements DBIDRange {
+final class IntegerDBIDRange implements IntegerDBIDs, DBIDRange, SetDBIDs {
/**
* Start value.
*/
@@ -72,8 +71,77 @@ class IntegerDBIDRange implements DBIDRange {
}
@Override
- public DBIDArrayIter iter() {
- return new DBIDItr(start, len);
+ public boolean contains(DBIDRef o) {
+ int oid = o.internalGetIndex();
+ if (oid < start) {
+ return false;
+ }
+ if (oid >= start + len) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public DBID get(int i) {
+ if (i > len || i < 0) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+ return DBIDFactory.FACTORY.importInteger(start + i);
+ }
+
+ /**
+ * For storage array offsets.
+ *
+ * @param dbid ID reference
+ * @return array offset
+ */
+ @Override
+ public int getOffset(DBIDRef dbid) {
+ return dbid.internalGetIndex() - start;
+ }
+
+ @Override
+ public void assignVar(int index, DBIDVar var) {
+ if (var instanceof IntegerDBIDVar) {
+ ((IntegerDBIDVar) var).internalSetIndex(start + index);
+ } else {
+ // Much less efficient:
+ var.set(get(index));
+ }
+ }
+
+ @Override
+ public int binarySearch(DBIDRef key) {
+ int keyid = DBIDUtil.asInteger(key);
+ if (keyid < start) {
+ return -1;
+ }
+ final int off = keyid - start;
+ if (off < len) {
+ return off;
+ }
+ return -(len + 1);
+ }
+
+ @Override
+ public String toString() {
+ return "[" + start + " to " + (start + len - 1) + "]";
+ }
+
+ @Override
+ public final int mapDBIDToOffset(DBIDRef dbid) {
+ return dbid.internalGetIndex() - start;
+ }
+
+ @Override
+ public ArrayDBIDs slice(int begin, int end) {
+ return new IntegerDBIDRange(begin + start, end - begin);
+ }
+
+ @Override
+ public Itr iter() {
+ return new Itr(start, len);
}
/**
@@ -83,30 +151,29 @@ class IntegerDBIDRange implements DBIDRange {
*
* @apiviz.exclude
*/
- protected static class DBIDItr implements DBIDArrayIter, IntegerDBIDRef {
+ private final static class Itr implements IntegerDBIDArrayIter {
/**
* Current position.
*/
- int pos = 0;
-
+ private int pos;
+
/**
* Interval length.
*/
- final int len;
+ final private int len;
/**
* Interval start.
*/
- final int start;
-
+ final private int start;
+
/**
* Constructor.
- *
+ *
* @param start Interval start
* @param len Interval length
*/
- DBIDItr(int start, int len) {
- super();
+ public Itr(final int start, final int len) {
this.start = start;
this.len = len;
}
@@ -118,7 +185,7 @@ class IntegerDBIDRange implements DBIDRange {
@Override
public void advance() {
- pos++;
+ ++pos;
}
@Override
@@ -128,7 +195,7 @@ class IntegerDBIDRange implements DBIDRange {
@Override
public void retract() {
- pos--;
+ --pos;
}
@Override
@@ -156,68 +223,4 @@ class IntegerDBIDRange implements DBIDRange {
return Integer.toString(internalGetIndex());
}
}
-
- @Override
- public boolean contains(DBIDRef o) {
- int oid = DBIDUtil.asInteger(o);
- if(oid < start) {
- return false;
- }
- if(oid >= start + len) {
- return false;
- }
- return true;
- }
-
- @Override
- public DBID get(int i) {
- if(i > len || i < 0) {
- throw new ArrayIndexOutOfBoundsException();
- }
- return DBIDFactory.FACTORY.importInteger(start + i);
- }
-
- /**
- * For storage array offsets.
- *
- * @param dbid ID reference
- * @return array offset
- */
- @Override
- public int getOffset(DBIDRef dbid) {
- return dbid.internalGetIndex() - start;
- }
-
- @Override
- public void assignVar(int index, DBIDVar var) {
- if (var instanceof IntegerDBIDVar) {
- ((IntegerDBIDVar)var).internalSetIndex(start + index);
- } else {
- // Much less efficient:
- var.set(get(index));
- }
- }
-
- @Override
- public int binarySearch(DBIDRef key) {
- int keyid = DBIDUtil.asInteger(key);
- if(keyid < start) {
- return -1;
- }
- final int off = keyid - start;
- if(off < len) {
- return off;
- }
- return -(len + 1);
- }
-
- @Override
- public String toString() {
- return "[" + start + " to " + (start + len - 1) + "]";
- }
-
- @Override
- public int mapDBIDToOffset(DBIDRef dbid) {
- return dbid.internalGetIndex() - start;
- }
-} \ No newline at end of file
+}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java
index dc63b117..0e1e82a9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDRef.java
@@ -29,6 +29,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
* DBID reference that references an integer value.
*
* @author Erich Schubert
+ *
+ * @apiviz.landmark
*/
interface IntegerDBIDRef extends DBIDRef {
/**
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java
index 57d400df..9120c0d7 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDVar.java
@@ -23,8 +23,10 @@ package de.lmu.ifi.dbs.elki.database.ids.integer;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import de.lmu.ifi.dbs.elki.database.ids.ArrayDBIDs;
import de.lmu.ifi.dbs.elki.database.ids.DBID;
import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
@@ -87,13 +89,13 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
}
@Override
- public IntegerDBIDArrayIter iter() {
- return new DBIDItr();
+ public int size() {
+ return 1;
}
@Override
- public int size() {
- return 1;
+ public boolean isEmpty() {
+ return false;
}
@Override
@@ -107,6 +109,35 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
return id == o.internalGetIndex();
}
+ @Override
+ public void assignVar(int i, DBIDVar var) {
+ if (var instanceof IntegerDBIDVar) {
+ ((IntegerDBIDVar) var).internalSetIndex(i);
+ } else {
+ // Much less efficient:
+ var.set(get(i));
+ }
+ }
+
+ @Override
+ public ArrayDBIDs slice(int begin, int end) {
+ if (begin == 0 && end == 1) {
+ return this;
+ } else {
+ return DBIDUtil.EMPTYDBIDS;
+ }
+ }
+
+ @Override
+ public String toString() {
+ return Integer.toString(id);
+ }
+
+ @Override
+ public Itr iter() {
+ return new Itr();
+ }
+
/**
* Pseudo iterator for DBIDs interface.
*
@@ -114,53 +145,53 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
*
* @apiviz.exclude
*/
- protected class DBIDItr implements IntegerDBIDArrayIter, IntegerDBIDRef {
+ protected class Itr implements IntegerDBIDArrayIter, IntegerDBIDRef {
/**
* Iterator position: We use an integer so we can support retract().
*/
int pos = 0;
-
+
@Override
public void advance() {
pos++;
}
-
+
@Override
public void advance(int count) {
pos += count;
}
-
+
@Override
public void retract() {
pos--;
}
-
+
@Override
public void seek(int off) {
pos = off;
}
-
+
@Override
public int getOffset() {
return pos;
}
-
+
@Override
public int internalGetIndex() {
return IntegerDBIDVar.this.id;
}
-
+
@Override
public boolean valid() {
return (pos == 0);
}
-
+
@Override
public int hashCode() {
// Override, because we also are overriding equals.
return super.hashCode();
}
-
+
@Override
public boolean equals(Object other) {
if (other instanceof DBID) {
@@ -168,30 +199,10 @@ class IntegerDBIDVar implements DBIDVar, IntegerDBIDs {
}
return super.equals(other);
}
-
+
@Override
public String toString() {
return Integer.toString(internalGetIndex());
}
}
-
- @Override
- public boolean isEmpty() {
- return false;
- }
-
- @Override
- public void assignVar(int i, DBIDVar var) {
- if (var instanceof IntegerDBIDVar) {
- ((IntegerDBIDVar) var).internalSetIndex(i);
- } else {
- // Much less efficient:
- var.set(get(i));
- }
- }
-
- @Override
- public String toString() {
- return Integer.toString(id);
- }
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java
index 4acf91e6..14faa72a 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/IntegerDBIDs.java
@@ -28,6 +28,8 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
* Integer DBID collection.
*
* @author Erich Schubert
+ *
+ * @apiviz.has IntegerDBIDIter
*/
public interface IntegerDBIDs extends DBIDs {
@Override
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayDBIDs.java
deleted file mode 100644
index 6980176a..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayDBIDs.java
+++ /dev/null
@@ -1,192 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.integer;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import gnu.trove.list.TIntList;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
-import de.lmu.ifi.dbs.elki.logging.LoggingUtil;
-
-/**
- * Abstract base class for GNU Trove array based lists.
- *
- * @author Erich Schubert
- *
- * @apiviz.has IntegerDBID
- * @apiviz.has DBIDItr
- */
-public abstract class TroveArrayDBIDs implements IntegerArrayDBIDs {
- /**
- * Get the array store.
- *
- * @return the store
- */
- protected abstract TIntList getStore();
-
- @Override
- public IntegerDBIDArrayMIter iter() {
- return new DBIDItr(getStore());
- }
-
- @Override
- public DBID get(int index) {
- return new IntegerDBID(getStore().get(index));
- }
-
- @Override
- public void assignVar(int index, DBIDVar var) {
- if (var instanceof IntegerDBIDVar) {
- ((IntegerDBIDVar)var).internalSetIndex(getStore().get(index));
- } else {
- // Much less efficient:
- var.set(get(index));
- }
- }
-
- @Override
- public int size() {
- return getStore().size();
- }
-
- @Override
- public boolean isEmpty() {
- return getStore().isEmpty();
- }
-
- @Override
- public boolean contains(DBIDRef o) {
- return getStore().contains(DBIDUtil.asInteger(o));
- }
-
- @Override
- public int binarySearch(DBIDRef key) {
- return getStore().binarySearch(DBIDUtil.asInteger(key));
- }
-
- @Override
- public String toString() {
- StringBuilder buf = new StringBuilder();
- buf.append('[');
- for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if(buf.length() > 1) {
- buf.append(", ");
- }
- buf.append(((IntegerDBIDRef) iter).internalGetIndex());
- }
- buf.append(']');
- return buf.toString();
- }
-
- /**
- * Iterate over a Trove IntList, ELKI/C-style.
- *
- * @author Erich Schubert
- *
- * @apiviz.exclude
- */
- protected static class DBIDItr implements IntegerDBIDArrayMIter {
- /**
- * Current position.
- */
- int pos = 0;
-
- /**
- * The actual store we use.
- */
- TIntList store;
-
- /**
- * Constructor.
- *
- * @param store The actual trove store
- */
- public DBIDItr(TIntList store) {
- super();
- this.store = store;
- }
-
- @Override
- public boolean valid() {
- return pos < store.size() && pos >= 0;
- }
-
- @Override
- public void advance() {
- pos++;
- }
-
- @Override
- public void advance(int count) {
- pos += count;
- }
-
- @Override
- public void retract() {
- pos--;
- }
-
- @Override
- public void seek(int off) {
- pos = off;
- }
-
- @Override
- public int getOffset() {
- return pos;
- }
-
- @Override
- public int internalGetIndex() {
- return store.get(pos);
- }
-
- @Override
- public void remove() {
- store.removeAt(pos);
- pos--;
- }
-
- @Override
- public int hashCode() {
- // Since we add a warning to 'equals', we also override hashCode.
- return super.hashCode();
- }
-
- @Override
- public boolean equals(Object other) {
- if(other instanceof DBID) {
- LoggingUtil.warning("Programming error detected: DBIDItr.equals(DBID). Use DBIDUtil.equal(iter, id)!", new Throwable());
- }
- return super.equals(other);
- }
-
- @Override
- public String toString() {
- return Integer.toString(internalGetIndex());
- }
- }
-} \ No newline at end of file
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayModifiableDBIDs.java
deleted file mode 100644
index 41191b10..00000000
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveArrayModifiableDBIDs.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package de.lmu.ifi.dbs.elki.database.ids.integer;
-
-/*
- This file is part of ELKI:
- Environment for Developing KDD-Applications Supported by Index-Structures
-
- Copyright (C) 2013
- Ludwig-Maximilians-Universität München
- Lehr- und Forschungseinheit für Datenbanksysteme
- ELKI Development Team
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-import gnu.trove.list.array.TIntArrayList;
-
-import java.util.Comparator;
-
-import de.lmu.ifi.dbs.elki.database.ids.ArrayModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.DBID;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-
-/**
- * Class using a GNU Trove int array list as storage.
- *
- * @author Erich Schubert
- */
-class TroveArrayModifiableDBIDs extends TroveArrayDBIDs implements ArrayModifiableDBIDs {
- /**
- * The actual trove array list
- */
- private TIntArrayList store;
-
- /**
- * Constructor.
- *
- * @param size Initial size
- */
- protected TroveArrayModifiableDBIDs(int size) {
- super();
- this.store = new TIntArrayList(size);
- }
-
- /**
- * Constructor.
- */
- protected TroveArrayModifiableDBIDs() {
- super();
- this.store = new TIntArrayList();
- }
-
- /**
- * Constructor.
- *
- * @param existing Existing ids
- */
- protected TroveArrayModifiableDBIDs(DBIDs existing) {
- this(existing.size());
- this.addDBIDs(existing);
- }
-
- @Override
- protected TIntArrayList getStore() {
- return store;
- }
-
- @Override
- public boolean addDBIDs(DBIDs ids) {
- boolean success = false;
- store.ensureCapacity(ids.size());
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
- success |= store.add(DBIDUtil.asInteger(iter));
- }
- return success;
- }
-
- @Override
- public boolean removeDBIDs(DBIDs ids) {
- boolean success = false;
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
- success |= store.remove(DBIDUtil.asInteger(id));
- }
- return success;
- }
-
- @Override
- public boolean add(DBIDRef e) {
- return store.add(DBIDUtil.asInteger(e));
- }
-
- @Override
- public boolean remove(DBIDRef o) {
- return store.remove(DBIDUtil.asInteger(o));
- }
-
- @Override
- public DBID set(int index, DBIDRef element) {
- int prev = store.set(index, DBIDUtil.asInteger(element));
- return new IntegerDBID(prev);
- }
-
- @Override
- public DBID remove(int index) {
- return new IntegerDBID(store.removeAt(index));
- }
-
- @Override
- public void clear() {
- store.clear();
- }
-
- @Override
- public void sort() {
- store.sort();
- }
-
- @Override
- public void sort(Comparator<? super DBIDRef> comparator) {
- // TODO: we no longer produce a lot of DBIDs anymore, but it would be even
- // cooler if we could access store._data directly...
- int[] data = store.toArray();
- IntegerDBIDArrayQuickSort.sort(data, comparator);
- store.clear();
- store.add(data);
- }
-
- @Override
- public void sort(int start, int end, Comparator<? super DBIDRef> comparator) {
- // TODO: we no longer produce a lot of DBIDs anymore, but it would be even
- // cooler if we could access store._data directly...
- int[] data = store.toArray();
- IntegerDBIDArrayQuickSort.sort(data, start, end, comparator);
- store.clear();
- store.add(data);
- }
-
- @Override
- public void swap(int a, int b) {
- store.set(a, store.set(b, store.get(a)));
- }
-}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java
index 9ebdccea..35276606 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/TroveHashSetModifiableDBIDs.java
@@ -1,16 +1,5 @@
package de.lmu.ifi.dbs.elki.database.ids.integer;
-import gnu.trove.impl.hash.THashPrimitiveIterator;
-import gnu.trove.impl.hash.TIntHash;
-import gnu.trove.set.hash.TIntHashSet;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
-import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
-import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
-import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter;
-
/*
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
@@ -34,13 +23,23 @@ import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter;
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+import gnu.trove.impl.hash.THashPrimitiveIterator;
+import gnu.trove.impl.hash.TIntHash;
+import gnu.trove.set.hash.TIntHashSet;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDMIter;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDRef;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDs;
+import de.lmu.ifi.dbs.elki.database.ids.HashSetModifiableDBIDs;
+import de.lmu.ifi.dbs.elki.utilities.datastructures.iterator.Iter;
+
/**
* Implementation using GNU Trove Int Hash Sets.
*
* @author Erich Schubert
*
- * @apiviz.has IntegerDBID
- * @apiviz.has DBIDItr
+ * @apiviz.has Itr
*/
class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBIDs {
/**
@@ -77,15 +76,15 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
}
@Override
- public IntegerDBIDMIter iter() {
- return new DBIDItr(store);
+ public Itr iter() {
+ return new Itr(store);
}
@Override
public boolean addDBIDs(DBIDs ids) {
store.ensureCapacity(ids.size());
boolean success = false;
- for (DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
+ for(DBIDIter iter = ids.iter(); iter.valid(); iter.advance()) {
success |= store.add(DBIDUtil.asInteger(iter));
}
return success;
@@ -94,7 +93,7 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
@Override
public boolean removeDBIDs(DBIDs ids) {
boolean success = false;
- for (DBIDIter id = ids.iter(); id.valid(); id.advance()) {
+ for(DBIDIter id = ids.iter(); id.valid(); id.advance()) {
success |= store.remove(DBIDUtil.asInteger(id));
}
return success;
@@ -113,8 +112,8 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
@Override
public boolean retainAll(DBIDs set) {
boolean modified = false;
- for (DBIDMIter it = iter(); it.valid(); it.advance()) {
- if (!set.contains(it)) {
+ for(DBIDMIter it = iter(); it.valid(); it.advance()) {
+ if(!set.contains(it)) {
it.remove();
modified = true;
}
@@ -146,8 +145,8 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
public String toString() {
StringBuilder buf = new StringBuilder();
buf.append('[');
- for (DBIDIter iter = iter(); iter.valid(); iter.advance()) {
- if (buf.length() > 1) {
+ for(DBIDIter iter = iter(); iter.valid(); iter.advance()) {
+ if(buf.length() > 1) {
buf.append(", ");
}
buf.append(iter.toString());
@@ -163,7 +162,7 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
*
* @apiviz.exclude
*/
- protected static class DBIDItr implements IntegerDBIDMIter {
+ protected static class Itr implements IntegerDBIDMIter {
/**
* The actual iterator. We don't have multi inheritance.
*/
@@ -174,7 +173,7 @@ class TroveHashSetModifiableDBIDs implements HashSetModifiableDBIDs, IntegerDBID
*
* @param hash Trove hash
*/
- public DBIDItr(TIntHash hash) {
+ public Itr(TIntHash hash) {
super();
this.it = new TIntHashItr(hash);
}
diff --git a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java
index ba30f54f..d1c37ab9 100644
--- a/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java
+++ b/src/de/lmu/ifi/dbs/elki/database/ids/integer/UnmodifiableIntegerArrayDBIDs.java
@@ -33,7 +33,7 @@ import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
*
* @author Erich Schubert
*
- * @apiviz.uses TroveArrayDBIDs
+ * @apiviz.uses IntegerArrayDBIDs
* @apiviz.has UnmodifiableDBIDIter
*/
public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs {
@@ -96,6 +96,11 @@ public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs {
return inner.binarySearch(key);
}
+ @Override
+ public IntegerArrayDBIDs slice(int begin, int end) {
+ return new UnmodifiableIntegerArrayDBIDs(inner.slice(begin, end));
+ }
+
/**
* Make an existing DBIDMIter unmodifiable.
*
@@ -151,7 +156,7 @@ public class UnmodifiableIntegerArrayDBIDs implements IntegerArrayStaticDBIDs {
public int internalGetIndex() {
return it.internalGetIndex();
}
-
+
@Override
public String toString() {
return it.toString();