Skip to content
Permalink
Browse files

storage: Support ranges in optimized blob reader path

MojoBlobReader calls BlobReader::SetReadRange if a range is set,
and this was previously ignored in the ReadSingleMojoDataItem
optimized reading path.

(cherry picked from commit 003a8d9)

Bug: 1049096
Change-Id: Iec9e39d03b2e49e0c3db0df0e4bb52c05d299cac
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2042731
Commit-Queue: enne <enne@chromium.org>
Reviewed-by: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: Marijn Kruisselbrink <mek@chromium.org>
Reviewed-by: Ben Kelly <wanderview@chromium.org>
Cr-Original-Commit-Position: refs/heads/master@{#739610}
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2076437
Reviewed-by: enne <enne@chromium.org>
Cr-Commit-Position: refs/branch-heads/3987@{#960}
Cr-Branched-From: c4e8da9-refs/heads/master@{#722274}
  • Loading branch information
quisquous authored and Commit Bot committed Feb 26, 2020
1 parent 9470738 commit 4d094ecbee33b0065510916b34f16625c4eec380
Showing with 53 additions and 3 deletions.
  1. +4 −3 storage/browser/blob/blob_reader.cc
  2. +49 −0 storage/browser/blob/blob_reader_unittest.cc
@@ -257,10 +257,11 @@ void BlobReader::ReadSingleMojoDataItem(
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(IsSingleMojoDataItem());

// Read the entire data item.
// Read the set range of this single data item.
auto item = blob_data_->items()[0];
item->data_handle()->Read(std::move(producer), item->offset(), item->length(),
std::move(done));
item->data_handle()->Read(std::move(producer),
item->offset() + current_item_offset_,
remaining_bytes_, std::move(done));
}

void BlobReader::Kill() {
@@ -686,6 +686,55 @@ TEST_F(BlobReaderTest, ReadableDataHandleSingle) {
EXPECT_EQ(0, memcmp(buffer.data(), kData.c_str(), kData.size()));
}

// This test is the same as ReadableDataHandleSingle, but adds the
// additional wrinkle of a SetReadRange call.
TEST_F(BlobReaderTest, ReadableDataHandleSingleRange) {
auto b = std::make_unique<BlobDataBuilder>("uuid");
const std::string kOrigData = "12345 Test Blob Data 12345";
auto data_handle =
base::MakeRefCounted<storage::FakeBlobDataHandle>(kOrigData, "");
b->AppendReadableDataHandle(data_handle, 6, 14);
this->InitializeReader(std::move(b));
const std::string kData = kOrigData.substr(6, 14);

int size_result = -1;
EXPECT_FALSE(IsReaderTotalSizeCalculated());
EXPECT_EQ(BlobReader::Status::DONE, reader_->CalculateSize(base::BindOnce(
&SetValue<int>, &size_result)));
CheckSizeCalculatedSynchronously(kData.size(), size_result);

// This test checks the optimized single mojo data item path, where the
// data pipe passed in gets passed directly to the MojoDataItem.
EXPECT_TRUE(reader_->IsSingleMojoDataItem());

uint64_t range_start = 3;
uint64_t range_length = 6;
reader_->SetReadRange(range_start, range_length);

mojo::ScopedDataPipeProducerHandle producer;
mojo::ScopedDataPipeConsumerHandle consumer;
MojoResult pipe_result = mojo::CreateDataPipe(nullptr, &producer, &consumer);
ASSERT_EQ(MOJO_RESULT_OK, pipe_result);

int bytes_read = net::ERR_UNEXPECTED;
reader_->ReadSingleMojoDataItem(
std::move(producer),
base::BindLambdaForTesting([&](int result) { bytes_read = result; }));
base::RunLoop().RunUntilIdle();

ASSERT_EQ(range_length, static_cast<uint64_t>(bytes_read));

std::vector<uint8_t> buffer(bytes_read);
uint32_t num_bytes = bytes_read;
MojoReadDataFlags flags = MOJO_READ_DATA_FLAG_ALL_OR_NONE;
MojoResult read_result = consumer->ReadData(buffer.data(), &num_bytes, flags);
ASSERT_EQ(MOJO_RESULT_OK, read_result);
ASSERT_EQ(range_length, num_bytes);

EXPECT_EQ(0,
memcmp(buffer.data(), kData.c_str() + range_start, range_length));
}

TEST_F(BlobReaderTest, ReadableDataHandleMultipleSlices) {
auto b = std::make_unique<BlobDataBuilder>("uuid");
const std::string kData1 = "Test Blob Data";

0 comments on commit 4d094ec

Please sign in to comment.
You can’t perform that action at this time.