summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java113
1 files changed, 81 insertions, 32 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
index 4f57cac8..da72ac1b 100644
--- a/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
+++ b/src/de/lmu/ifi/dbs/elki/datasource/bundle/BundleReader.java
@@ -4,7 +4,7 @@ package de.lmu.ifi.dbs.elki.datasource.bundle;
This file is part of ELKI:
Environment for Developing KDD-Applications Supported by Index-Structures
- Copyright (C) 2013
+ Copyright (C) 2014
Ludwig-Maximilians-Universität München
Lehr- und Forschungseinheit für Datenbanksysteme
ELKI Development Team
@@ -26,13 +26,15 @@ import java.io.IOException;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.FileChannel.MapMode;
-import java.util.ArrayList;
import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
import de.lmu.ifi.dbs.elki.data.type.TypeInformationSerializer;
-import de.lmu.ifi.dbs.elki.persistent.ByteArrayUtil;
-import de.lmu.ifi.dbs.elki.persistent.ByteBufferSerializer;
+import de.lmu.ifi.dbs.elki.data.type.TypeUtil;
+import de.lmu.ifi.dbs.elki.database.ids.DBID;
+import de.lmu.ifi.dbs.elki.database.ids.DBIDVar;
import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteArrayUtil;
+import de.lmu.ifi.dbs.elki.utilities.io.ByteBufferSerializer;
/**
* Read an ELKI bundle file into a data stream.
@@ -41,7 +43,8 @@ import de.lmu.ifi.dbs.elki.utilities.exceptions.AbortException;
*
* @author Erich Schubert
*
- * @apiviz.uses FileChannel
+ * @apiviz.uses MappedByteBuffer - - «reads»
+ * @apiviz.uses FileChannel - - «reads»
*/
public class BundleReader implements BundleStreamSource {
/**
@@ -52,7 +55,7 @@ public class BundleReader implements BundleStreamSource {
/**
* The stream buffer.
*/
- MappedByteBuffer buffer;
+ MappedByteBuffer buffer = null;
/**
* Bundle metadata.
@@ -62,17 +65,33 @@ public class BundleReader implements BundleStreamSource {
/**
* Input channel.
*/
- FileChannel input;
+ FileChannel input = null;
/**
* Serializers to use.
*/
- ArrayList<ByteBufferSerializer<?>> sers;
+ ByteBufferSerializer<?>[] sers;
/**
* Current object.
*/
- ArrayList<Object> data;
+ Object[] data;
+
+ /**
+ * Whether or not we have DBIDs.
+ */
+ boolean hasids = false;
+
+ /**
+ * Constructor.
+ *
+ * @param buffer Input buffer
+ */
+ public BundleReader(MappedByteBuffer buffer) {
+ super();
+ this.buffer = buffer;
+ this.input = null;
+ }
/**
* Constructor.
@@ -86,7 +105,7 @@ public class BundleReader implements BundleStreamSource {
@Override
public BundleMeta getMeta() {
- if (meta == null) {
+ if(meta == null) {
openBuffer();
readMeta();
}
@@ -97,10 +116,13 @@ public class BundleReader implements BundleStreamSource {
* Map the input file.
*/
void openBuffer() {
- try {
- buffer = input.map(MapMode.READ_ONLY, 0, input.size());
- } catch (IOException e) {
- throw new AbortException("Cannot map input bundle.", e);
+ if(buffer == null) {
+ try {
+ buffer = input.map(MapMode.READ_ONLY, 0, input.size());
+ }
+ catch(IOException e) {
+ throw new AbortException("Cannot map input bundle.", e);
+ }
}
}
@@ -109,23 +131,30 @@ public class BundleReader implements BundleStreamSource {
*/
void readMeta() {
final int check = buffer.getInt();
- if (check != MAGIC) {
+ if(check != MAGIC) {
throw new AbortException("File does not start with expected magic.");
}
final int nummeta = buffer.getInt();
- assert (nummeta > 0);
+ assert (nummeta > 0) : "Empty bundle?";
meta = new BundleMeta(nummeta);
- sers = new ArrayList<>(nummeta);
- data = new ArrayList<>(nummeta);
- for (int i = 0; i < nummeta; i++) {
+ sers = new ByteBufferSerializer<?>[nummeta];
+ data = new Object[nummeta];
+ for(int i = 0; i < nummeta; i++) {
try {
@SuppressWarnings("unchecked")
SimpleTypeInformation<? extends Object> type = (SimpleTypeInformation<? extends Object>) TypeInformationSerializer.STATIC.fromByteBuffer(buffer);
- meta.add(type);
- sers.add(type.getSerializer());
- } catch (UnsupportedOperationException e) {
- throw new AbortException("Deserialization failed: "+e.getMessage(), e);
- } catch (IOException e) {
+ sers[i] = type.getSerializer();
+ if(i == 0 && TypeUtil.DBID.isAssignableFromType(type)) {
+ hasids = true;
+ }
+ else {
+ meta.add(type);
+ }
+ }
+ catch(UnsupportedOperationException e) {
+ throw new AbortException("Deserialization failed: " + e.getMessage(), e);
+ }
+ catch(IOException e) {
throw new AbortException("IO error", e);
}
}
@@ -135,13 +164,14 @@ public class BundleReader implements BundleStreamSource {
* Read an object.
*/
void readObject() {
- data.clear();
- for (ByteBufferSerializer<?> ser : sers) {
+ for(int i = 0; i < sers.length; ++i) {
try {
- data.add(ser.fromByteBuffer(buffer));
- } catch (UnsupportedOperationException e) {
+ data[i] = sers[i].fromByteBuffer(buffer);
+ }
+ catch(UnsupportedOperationException e) {
throw new AbortException("Deserialization failed.", e);
- } catch (IOException e) {
+ }
+ catch(IOException e) {
throw new AbortException("IO error", e);
}
}
@@ -150,10 +180,10 @@ public class BundleReader implements BundleStreamSource {
@Override
public Event nextEvent() {
// Send initial meta
- if (meta == null) {
+ if(meta == null) {
return Event.META_CHANGED;
}
- if (buffer.remaining() == 0) {
+ if(buffer.remaining() == 0) {
ByteArrayUtil.unmapByteBuffer(buffer);
return Event.END_OF_STREAM;
}
@@ -163,6 +193,25 @@ public class BundleReader implements BundleStreamSource {
@Override
public Object data(int rnum) {
- return data.get(rnum);
+ return data[!hasids ? rnum : (rnum + 1)];
+ }
+
+ @Override
+ public boolean hasDBIDs() {
+ return hasids;
+ }
+
+ @Override
+ public boolean assignDBID(DBIDVar var) {
+ if(!hasids) {
+ return false;
+ }
+ var.set((DBID) data[0]);
+ return true;
+ }
+
+ @Override
+ public MultipleObjectsBundle asMultipleObjectsBundle() {
+ return MultipleObjectsBundle.fromStream(this);
}
}