CompletableFuture<Long> getLength(Duration timeout) { return CompletableFuture.supplyAsync(() -> { synchronized (this.data) { return (long) this.data.size(); } }, executorService()); }
@Override public CompletableFuture<Long> append(byte[] data, Collection<AttributeUpdate> attributeUpdates, Duration timeout) { return CompletableFuture.supplyAsync(() -> { // Note that this append is not atomic (data & attributes) - but for testing purposes it does not matter as // this method should only be used for constructing the test data. long offset; synchronized (this) { offset = this.contents.size(); this.contents.write(data); if (attributeUpdates != null) { val updatedValues = new HashMap<UUID, Long>(); attributeUpdates.forEach(update -> collectAttributeValue(update, updatedValues)); this.metadata.updateAttributes(updatedValues); } this.metadata.setLength(this.contents.size()); } return offset; }, this.executor); }
synchronized (this.data) { if (toWrite.isEmpty()) { return (long) this.data.size(); long originalOffset = this.data.size(); long expectedOffset = this.data.size(); for (val e : toWrite) { Preconditions.checkArgument(expectedOffset == e.getKey(), "Bad Offset. Expected %s, given %s.", assert expectedOffset == this.data.size() : "unexpected number of bytes copied"; .map(Map.Entry::getKey) .min(Long::compare) .orElse((long) this.data.size()); Assert.assertEquals("Unexpected truncation offset.", expectedTruncationOffset, truncateOffset); .collect(Collectors.toList()); toRemove.forEach(this.offsets::remove); return (long) this.data.size();
@Override public boolean processEntry(ReadResultEntry entry) { if (this.result.isDone()) { // We are done. Nothing else to do. return false; } try { Preconditions.checkArgument(entry.getContent().isDone(), "Entry Contents is not yet fetched."); ReadResultEntryContents contents = entry.getContent().join(); // TODO: most of these transfers are from memory to memory. It's a pity that we need an extra buffer to do the copy. // TODO: https://github.com/pravega/pravega/issues/2924 this.readData.write(StreamHelpers.readAll(contents.getData(), contents.getLength())); if (this.header == null && this.readData.size() >= EntrySerializer.HEADER_LENGTH) { // We now have enough to read the header. this.header = this.serializer.readHeader(this.readData.getData()); } if (this.header != null) { return !processReadData(this.readData.getData()); } return true; // Not done yet. } catch (Throwable ex) { processError(ex); return false; } }
() -> { rnd.nextBytes(writeBuffer); return oldStorage.write(handle, writtenData.size(), new ByteArrayInputStream(writeBuffer), writeBuffer.length, TIMEOUT) .thenRun(() -> writtenData.write(writeBuffer)); },
private <T> void testEncodeDecode(BiConsumerWithException<RevisionDataOutputStream, T> write, FunctionWithException<RevisionDataInputStream, T> read, BiFunction<RevisionDataOutputStream, T, Integer> getLength, T value, BiPredicate<T, T> equalityTester) throws Exception { @Cleanup val os = new EnhancedByteArrayOutputStream(); @Cleanup val rdos = RevisionDataOutputStream.wrap(os); write.accept(rdos, value); rdos.close(); os.close(); val actualLength = os.size() - Integer.BYTES; // Subtract 4 because this is the Length being encoded. Assert.assertEquals("Unexpected length for value " + value, (int) getLength.apply(rdos, value), actualLength); @Cleanup val rdis = RevisionDataInputStream.wrap(os.getData().getReader()); val actualValue = read.apply(rdis); Assert.assertTrue(String.format("Encoding/decoding failed for %s (decoded %s).", value, actualValue), equalityTester.test(value, actualValue)); }