diff options
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.java | 113 |
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); } } |