public IRandomAccessSource createRanged(IRandomAccessSource source, long[] ranges) throws java.io.IOException { IRandomAccessSource[] sources = new IRandomAccessSource[ranges.length/2]; for(int i = 0; i < ranges.length; i+=2){ sources[i/2] = new WindowRandomAccessSource(source, ranges[i], ranges[i+1]); } return new GroupedRandomAccessSource(sources); }
/** * {@inheritDoc} * Cleans the mapped bytebuffers and closes the channel */ @Override public void close() throws java.io.IOException { try { super.close(); } finally { try { channel.close(); } catch (Exception ex) { Logger logger = LoggerFactory.getLogger(PagedChannelRandomAccessSource.class); logger.error(LogMessageConstant.FILE_CHANNEL_CLOSING_FAILED, ex); } } }
/** * Returns the SourceEntry that contains the byte at the specified offset * sourceReleased is called as a notification callback so subclasses can take care of cleanup * when the source is no longer the active source * @param offset the offset of the byte to look for * @return the SourceEntry that contains the byte at the specified offset * @throws java.io.IOException if there is a problem with IO (usually the result of the sourceReleased() call) */ private SourceEntry getSourceEntryForOffset(long offset) throws java.io.IOException { if (offset >= size) return null; if (offset >= currentSourceEntry.firstByte && offset <= currentSourceEntry.lastByte) return currentSourceEntry; // hook to allow subclasses to release resources if necessary sourceReleased(currentSourceEntry.source); int startAt = getStartingSourceIndex(offset); for(int i = startAt; i < sources.length; i++){ if (offset >= sources[i].firstByte && offset <= sources[i].lastByte){ currentSourceEntry = sources[i]; sourceInUse(currentSourceEntry.source); return currentSourceEntry; } } return null; }
/** * {@inheritDoc} * The source that contains the byte at position is retrieved, the correct offset into that source computed, then the value * from that offset in the underlying source is returned. */ public int get(long position) throws java.io.IOException { SourceEntry entry = getSourceEntryForOffset(position); if (entry == null) // we have run out of data to read from return -1; return entry.source.get(entry.offsetN(position)); }
/** * Constructs a new {@link GroupedRandomAccessSource} based on the specified set of sources * @param sources the sources used to build this group */ public GroupedRandomAccessSource(IRandomAccessSource[] sources) throws java.io.IOException { this.sources = new SourceEntry[sources.length]; long totalSize = 0; for(int i = 0; i < sources.length; i++){ this.sources[i] = new SourceEntry(i, sources[i], totalSize); totalSize += sources[i].length(); } size = totalSize; currentSourceEntry = this.sources[sources.length-1]; sourceInUse(currentSourceEntry.source); }
/** * {@inheritDoc} * The source that contains the byte at position is retrieved, the correct offset into that source computed, then the value * from that offset in the underlying source is returned. */ public int get(long position) throws java.io.IOException { SourceEntry entry = getSourceEntryForOffset(position); if (entry == null) // we have run out of data to read from return -1; return entry.source.get(entry.offsetN(position)); }
/** * Constructs a new {@link GroupedRandomAccessSource} based on the specified set of sources * @param sources the sources used to build this group */ public GroupedRandomAccessSource(IRandomAccessSource[] sources) throws java.io.IOException { this.sources = new SourceEntry[sources.length]; long totalSize = 0; for(int i = 0; i < sources.length; i++){ this.sources[i] = new SourceEntry(i, sources[i], totalSize); totalSize += sources[i].length(); } size = totalSize; currentSourceEntry = this.sources[sources.length-1]; sourceInUse(currentSourceEntry.source); }
/** * Returns the SourceEntry that contains the byte at the specified offset * sourceReleased is called as a notification callback so subclasses can take care of cleanup * when the source is no longer the active source * @param offset the offset of the byte to look for * @return the SourceEntry that contains the byte at the specified offset * @throws java.io.IOException if there is a problem with IO (usually the result of the sourceReleased() call) */ private SourceEntry getSourceEntryForOffset(long offset) throws java.io.IOException { if (offset >= size) return null; if (offset >= currentSourceEntry.firstByte && offset <= currentSourceEntry.lastByte) return currentSourceEntry; // hook to allow subclasses to release resources if necessary sourceReleased(currentSourceEntry.source); int startAt = getStartingSourceIndex(offset); for(int i = startAt; i < sources.length; i++){ if (offset >= sources[i].firstByte && offset <= sources[i].lastByte){ currentSourceEntry = sources[i]; sourceInUse(currentSourceEntry.source); return currentSourceEntry; } } return null; }
/** * {@inheritDoc} */ public int get(long position, byte[] bytes, int off, int len) throws java.io.IOException { SourceEntry entry = getSourceEntryForOffset(position); if (entry == null) // we have run out of data to read from return -1; long offN = entry.offsetN(position); int remaining = len; while(remaining > 0){ if (entry == null) // we have run out of data to read from break; if (offN > entry.source.length()) break; int count = entry.source.get(offN, bytes, off, remaining); if (count == -1) break; off += count; position += count; remaining -= count; offN = 0; entry = getSourceEntryForOffset(position); } return remaining == len ? -1 : len - remaining; }
public IRandomAccessSource createRanged(IRandomAccessSource source, long[] ranges) throws java.io.IOException { IRandomAccessSource[] sources = new IRandomAccessSource[ranges.length/2]; for(int i = 0; i < ranges.length; i+=2){ sources[i/2] = new WindowRandomAccessSource(source, ranges[i], ranges[i+1]); } return new GroupedRandomAccessSource(sources); }
/** * {@inheritDoc} * Cleans the mapped bytebuffers and closes the channel */ @Override public void close() throws java.io.IOException { try { super.close(); } finally { try { channel.close(); } catch (Exception ex) { Logger logger = LoggerFactory.getLogger(PagedChannelRandomAccessSource.class); logger.error(LogMessageConstant.FILE_CHANNEL_CLOSING_FAILED, ex); } } }
/** * {@inheritDoc} */ public int get(long position, byte[] bytes, int off, int len) throws java.io.IOException { SourceEntry entry = getSourceEntryForOffset(position); if (entry == null) // we have run out of data to read from return -1; long offN = entry.offsetN(position); int remaining = len; while(remaining > 0){ if (entry == null) // we have run out of data to read from break; if (offN > entry.source.length()) break; int count = entry.source.get(offN, bytes, off, remaining); if (count == -1) break; off += count; position += count; remaining -= count; offN = 0; entry = getSourceEntryForOffset(position); } return remaining == len ? -1 : len - remaining; }