use of io.pravega.common.util.BufferView in project pravega by pravega.
the class S3Mock method putObject.
public void putObject(String bucketName, String key, Range range, Object content) {
String objectName = getObjectName(bucketName, key);
synchronized (this.objects) {
ObjectData od = this.objects.get(objectName);
if (od == null) {
throw new S3Exception(String.format("Object '%s/%s' does not exist.", bucketName, key), 404, "NoSuchKey", key);
}
final int startOffset = (int) (long) range.getFirst();
final int length = (int) (range.getLast() + 1 - range.getFirst());
BufferView objectContent = od.content;
if (startOffset < objectContent.getLength()) {
objectContent = new ByteArraySegment(objectContent.slice(0, startOffset).getCopy());
} else if (startOffset > objectContent.getLength()) {
throw new S3Exception("", HttpStatus.SC_REQUESTED_RANGE_NOT_SATISFIABLE, "InvalidRange", "");
}
InputStream source = (InputStream) content;
byte[] buffer = new byte[length];
try {
int copyLength = StreamHelpers.readAll(source, buffer, 0, length);
assert copyLength == length;
} catch (IOException ex) {
throw new S3Exception("Copy error", HttpStatus.SC_INTERNAL_SERVER_ERROR);
}
od.content = BufferView.wrap(Arrays.asList(objectContent, new ByteArraySegment(buffer)));
}
}
use of io.pravega.common.util.BufferView in project pravega by pravega.
the class ReadResult method readRemaining.
/**
* Reads the remaining contents of the ReadResult into the given array. This will stop when the given target has been
* filled or when the current end of the Segment has been reached.
*
* @param target A byte array where the ReadResult will be read into.
* @param fetchTimeout A timeout to use when needing to fetch the contents of an entry that is not in the Cache.
* @return The number of bytes read.
*/
@VisibleForTesting
default int readRemaining(byte[] target, Duration fetchTimeout) {
int bytesRead = 0;
while (hasNext() && bytesRead < target.length) {
ReadResultEntry entry = next();
if (entry.getType() == ReadResultEntryType.EndOfStreamSegment || entry.getType() == ReadResultEntryType.Future) {
// Reached the end.
break;
} else if (!entry.getContent().isDone()) {
entry.requestContent(fetchTimeout);
}
BufferView contents = entry.getContent().join();
int copied = contents.copyTo(ByteBuffer.wrap(target, bytesRead, Math.min(contents.getLength(), target.length - bytesRead)));
bytesRead += copied;
}
return bytesRead;
}
use of io.pravega.common.util.BufferView in project pravega by pravega.
the class PravegaRequestProcessor method readTableEntriesDelta.
@Override
public void readTableEntriesDelta(WireCommands.ReadTableEntriesDelta readTableEntriesDelta) {
final String segment = readTableEntriesDelta.getSegment();
final String operation = "readTableEntriesDelta";
if (!verifyToken(segment, readTableEntriesDelta.getRequestId(), readTableEntriesDelta.getDelegationToken(), operation)) {
return;
}
final int suggestedEntryCount = readTableEntriesDelta.getSuggestedEntryCount();
final long fromPosition = readTableEntriesDelta.getFromPosition();
log.info(readTableEntriesDelta.getRequestId(), "Iterate Table Entries Delta: Segment={} Count={} FromPositon={}.", readTableEntriesDelta.getSegment(), readTableEntriesDelta.getSuggestedEntryCount(), readTableEntriesDelta.getFromPosition());
val timer = new Timer();
val result = new DeltaIteratorResult<BufferView, Map.Entry<WireCommands.TableKey, WireCommands.TableValue>>(segment.getBytes().length + WireCommands.TableEntriesRead.HEADER_BYTES);
tableStore.entryDeltaIterator(segment, fromPosition, TIMEOUT).thenCompose(itr -> itr.collectRemaining(e -> {
if (result.getItemCount() >= suggestedEntryCount || result.getSizeBytes() >= MAX_READ_SIZE) {
return false;
}
TableEntry entry = e.getEntries().iterator().next();
DeltaIteratorState state = DeltaIteratorState.deserialize(e.getState());
// Store all TableEntries.
val k = new WireCommands.TableKey(toByteBuf(entry.getKey().getKey()), entry.getKey().getVersion());
val v = new WireCommands.TableValue(toByteBuf(entry.getValue()));
if (state.isDeletionRecord()) {
result.remove(entry.getKey().getKey(), k.size() + v.size());
} else {
Map.Entry<WireCommands.TableKey, WireCommands.TableValue> old = result.getItem(entry.getKey().getKey());
if (old != null && old.getKey().getKeyVersion() < entry.getKey().getVersion()) {
int sizeBytes = (k.size() + v.size()) - (old.getKey().size() + old.getValue().size());
result.add(entry.getKey().getKey(), new AbstractMap.SimpleImmutableEntry<>(k, v), sizeBytes);
} else {
result.add(entry.getKey().getKey(), new AbstractMap.SimpleImmutableEntry<>(k, v), k.size() + v.size());
}
}
result.setState(state);
// Update total read data.
return true;
})).thenAccept(v -> {
log.debug(readTableEntriesDelta.getRequestId(), "Iterate Table Segment Entries Delta complete ({}).", result.getItemCount());
connection.send(new WireCommands.TableEntriesDeltaRead(readTableEntriesDelta.getRequestId(), segment, new WireCommands.TableEntries(result.getItems()), result.getState().isShouldClear(), result.getState().isReachedEnd(), result.getState().getFromPosition()));
this.tableStatsRecorder.iterateEntries(readTableEntriesDelta.getSegment(), result.getItemCount(), timer.getElapsed());
}).exceptionally(e -> handleException(readTableEntriesDelta.getRequestId(), segment, operation, e));
}
use of io.pravega.common.util.BufferView in project pravega by pravega.
the class PravegaRequestProcessor method collectCachedEntries.
/**
* Reads all of the cachedEntries from the ReadResult and puts their content into the cachedEntries list.
* Upon encountering a non-cached entry, it stops iterating and returns it.
*/
private ReadResultEntry collectCachedEntries(long initialOffset, ReadResult readResult, ArrayList<BufferView> cachedEntries) {
long expectedOffset = initialOffset;
while (readResult.hasNext()) {
ReadResultEntry entry = readResult.next();
if (entry.getType() == Cache) {
Preconditions.checkState(entry.getStreamSegmentOffset() == expectedOffset, "Data returned from read was not contiguous.");
BufferView content = entry.getContent().getNow(null);
expectedOffset += content.getLength();
cachedEntries.add(content);
} else {
return entry;
}
}
return null;
}
use of io.pravega.common.util.BufferView in project pravega by pravega.
the class StreamSegmentReadIndex method getMultiReadResultEntry.
/**
* Returns a ReadResultEntry that matches the specified search parameters.
* <p>
* Compared to getSingleMemoryReadResultEntry(), this method may return a direct entry or a collection of entries.
* If the first entry to be returned would constitute a cache hit, then this method will attempt to return data from
* subsequent (congruent) entries, as long as they are cache hits. If at any time a cache miss occurs, the data collected
* so far is returned as a single entry, excluding the cache miss entry (exception if the first entry is a miss,
* then that entry is returned).
*
* @param resultStartOffset The Offset within the StreamSegment where to start returning data from.
* @param maxLength The maximum number of bytes to return.
* @param makeCopy If true, any data retrieved from the Cache will be copied into a Heap buffer before being returned.
* @return A ReadResultEntry representing the data to return.
*/
private CompletableReadResultEntry getMultiReadResultEntry(long resultStartOffset, int maxLength, boolean makeCopy) {
int readLength = 0;
CompletableReadResultEntry nextEntry = getSingleReadResultEntry(resultStartOffset, maxLength, makeCopy);
if (nextEntry == null || !(nextEntry instanceof CacheReadResultEntry)) {
// We can only coalesce CacheReadResultEntries.
return nextEntry;
}
// Collect the contents of congruent Index Entries into a list, as long as we still encounter data in the cache.
ArrayList<BufferView> contents = new ArrayList<>();
do {
assert Futures.isSuccessful(nextEntry.getContent()) : "Found CacheReadResultEntry that is not completed yet: " + nextEntry;
val entryContents = nextEntry.getContent().join();
contents.add(entryContents);
readLength += entryContents.getLength();
if (readLength >= this.config.getMemoryReadMinLength() || readLength >= maxLength) {
break;
}
nextEntry = getSingleMemoryReadResultEntry(resultStartOffset + readLength, maxLength - readLength, makeCopy);
} while (nextEntry != null);
// Coalesce the results into a single InputStream and return the result.
return new CacheReadResultEntry(resultStartOffset, BufferView.wrap(contents));
}
Aggregations