@Override public void close() throws IOException { is.close(); } }
@Override public long tell() throws IOException { return is.getPos(); }
@Override public int read(byte[] b, int off, int len) throws IOException { return is.read(b, off, len); }
/** * Creates a {@link StreamEvent} that will be used as a template for all events consumable from this reader. */ private StreamEvent createEventTemplate(Map<String, String> properties) throws IOException { long timestamp = -1L; // See if all events in the file are of the same timestamp String uniTimestamp = properties.get(StreamDataFileConstants.Property.Key.UNI_TIMESTAMP); if (StreamDataFileConstants.Property.Value.CLOSE_TIMESTAMP.equals(uniTimestamp)) { // Seek to the end - 8 of the stream to read the close timestamp long pos = eventInput.getPos(); eventInput.seek(eventInput.size() - 8); timestamp = Math.abs(readTimestamp()); eventInput.seek(pos); } else if (uniTimestamp != null) { timestamp = Long.parseLong(uniTimestamp); } // Grab the set of default headers for all events ImmutableMap.Builder<String, String> headers = ImmutableMap.builder(); String prefix = StreamDataFileConstants.Property.Key.EVENT_HEADER_PREFIX; for (Map.Entry<String, String> entry : properties.entrySet()) { if (entry.getKey().startsWith(prefix)) { headers.put(entry.getKey().substring(prefix.length()), entry.getValue()); } } return new StreamEvent(headers.build(), ByteBuffers.EMPTY_BUFFER, timestamp); }
/** * Opens and initialize this reader. */ private void doOpen() throws IOException { try { eventInput = eventInputSupplier.getInput(); decoder = new BinaryDecoder(eventInput); // If position is <= 0, the reader is not being used yet, hence needs to initialize. if (position <= 0) { init(); } else { // If position > 0, the reader has already been initialized. // We just need to seek to beginning of a data-block, depending on whether there is event in the buffer if (streamEventBuffer.hasEvent()) { // If there is event in the buffer, we seek to the data block that come after the buffered events // to prepare for the reading of the data block after the current buffered events are fully consumed. eventInput.seek(streamEventBuffer.getEndPosition()); } else { // Otherwise, we seek to the current position, which should be pointing to the beginning of a data block eventInput.seek(position); } } } catch (IOException e) { if (eventInput != null) { eventInput.close(); eventInput = null; } throw e; } }
private void readDataBlock(ReadFilter filter) throws IOException { position = eventInput.getPos(); long timestamp = readTimestamp(); if (timestamp < 0) { eventInput.seek(position); initByTime(nextTimestamp); return; long bytesSkipped = eventInput.skip(length); if (bytesSkipped != length) { throw new EOFException("Expected to skip " + length + " but only " + bytesSkipped + " was skipped."); position = eventInput.getPos();
/** * Fills the internal buffer by reading from the given input stream. * * @param input input stream to read from * @param size number of bytes to read * @throws IOException if failed to read from the stream * @throws EOFException if failed to read the given number of bytes from the input */ void fillBuffer(SeekableInputStream input, int size) throws IOException { buffer.clear(); buffer = ensureCapacity(buffer, size); try { basePosition = input.getPos(); int bytesRead = 0; while (bytesRead != size) { int len = input.read(buffer.array(), bytesRead, size - bytesRead); if (len < 0) { throw new EOFException("Expected to read " + size + ", but only " + bytesRead + " was read"); } bytesRead += len; } buffer.limit(size); bufferInput.reset(buffer); } catch (IOException e) { // Make the buffer has nothing to read buffer.position(buffer.limit()); basePosition = -1L; throw e; } }
@Override public void seek(long p) throws IOException { is.seek(p); }
@Override public void seek(long p) throws IOException { is.seek(p); }
@Override public void close() throws IOException { is.close(); } }
private void initByOffset(final long offset) throws IOException { // If index is provided, lookup the position smaller but closest to the offset. StreamDataFileIndex index = getIndex(); long pos = index == null ? 0 : index.floorPosition(offset); if (pos > 0) { eventInput.seek(pos); } skipUntil(new SkipCondition() { @Override public boolean apply(long position, long timestamp) { return position >= offset; } }); }
@Override public long tell() throws IOException { return is.getPos(); }
@Override public int read(byte[] b, int off, int len) throws IOException { return is.read(b, off, len); }
@Override public void close() throws IOException { if (closed) { return; } try { if (eventInput != null) { eventInput.close(); } } finally { closed = true; } }
private void initByTime(final long time) throws IOException { // If index is provided, lookup the index find the offset closest to start time. // If no offset is found, starts from the beginning of the events StreamDataFileIndex index = getIndex(); long offset = index == null ? 0 : index.floorPositionByTime(time); if (offset > 0) { eventInput.seek(offset); } skipUntil(new SkipCondition() { @Override public boolean apply(long position, long timestamp) { return timestamp >= time; } }); }
private void readHeader() throws IOException { // Read the header of the event file // First 2 bytes should be 'E' '1' byte[] magic = new byte[StreamDataFileConstants.MAGIC_HEADER_SIZE]; ByteStreams.readFully(eventInput, magic); int fileVersion = decodeFileVersion(magic); // Read the properties map. Map<String, String> properties = StreamUtils.decodeMap(new BinaryDecoder(eventInput)); verifySchema(properties); // Create event template if (fileVersion >= 2) { eventTemplate = createEventTemplate(properties); } else { eventTemplate = new StreamEvent(ImmutableMap.<String, String>of(), ByteBuffers.EMPTY_BUFFER, -1L); } position = eventInput.getPos(); }
@Override public void close() throws IOException { try { super.close(); } finally { if (sizeProvider instanceof Closeable) { Closeables.closeQuietly((Closeable) sizeProvider); } } } }
@Override public void close() throws IOException { try { super.close(); } finally { if (sizeProvider instanceof Closeable) { Closeables.closeQuietly((Closeable) sizeProvider); } } } }
eventInput.close(); eventInput = null;