| 602 | } |
| 603 | |
| 604 | CoTask<void> randomWrite(MetaClient &meta, |
| 605 | storage::client::StorageClient &client, |
| 606 | Inode &inode, |
| 607 | uint64_t offset, |
| 608 | uint64_t length) { |
| 609 | auto stripe = std::min((uint32_t)folly::divCeil(offset + length, (uint64_t)inode.asFile().layout.chunkSize), |
| 610 | inode.asFile().layout.stripeSize); |
| 611 | if (inode.asFile().dynStripe && inode.asFile().dynStripe < stripe) { |
| 612 | auto result = co_await meta.extendStripe(flat::UserInfo{}, inode.id, stripe); |
| 613 | CO_ASSERT_OK(result); |
| 614 | inode = *result; |
| 615 | } |
| 616 | |
| 617 | uint64_t chunkSize = inode.asFile().layout.chunkSize; |
| 618 | std::vector<uint8_t> writeData(chunkSize, 0x00); |
| 619 | std::vector<folly::SemiFuture<folly::Unit>> tasks; |
| 620 | while (length) { |
| 621 | auto offsetInChunk = offset % chunkSize; |
| 622 | auto lengthInChunk = std::min(length, chunkSize - offsetInChunk); |
| 623 | auto chunkId = inode.asFile().getChunkId(inode.id, offset); |
| 624 | auto routingInfo = client.getMgmtdClient().getRoutingInfo()->raw(); |
| 625 | XLOGF_IF(FATAL, !routingInfo, "No routingInfo"); |
| 626 | auto chainId = inode.asFile().getChainId(inode, offset, *routingInfo); |
| 627 | XLOGF_IF(FATAL, !chainId, "resolve chainId failed: {}", chainId); |
| 628 | |
| 629 | auto task = [=, &client, &writeData]() -> CoTask<void> { |
| 630 | auto writeIO = client.createWriteIO(storage::ChainId(*chainId), |
| 631 | storage::ChunkId(chunkId->pack()), |
| 632 | offsetInChunk, |
| 633 | lengthInChunk, |
| 634 | chunkSize, |
| 635 | writeData.data(), |
| 636 | nullptr); |
| 637 | XLOGF(DBG, "write {} offset {}, offsetInChunk {} length {}", chunkId, offset, offsetInChunk, lengthInChunk); |
| 638 | auto result = co_await client.write(writeIO, flat::UserInfo()); |
| 639 | CO_ASSERT_FALSE(result.hasError()) << result.error().describe(); |
| 640 | CO_ASSERT_FALSE(writeIO.result.lengthInfo.hasError()) << writeIO.result.lengthInfo.error().describe(); |
| 641 | CO_ASSERT_EQ(*writeIO.result.lengthInfo, lengthInChunk); |
| 642 | }; |
| 643 | |
| 644 | tasks.push_back(folly::coro::co_invoke(task).scheduleOn(co_await folly::coro::co_current_executor).start()); |
| 645 | |
| 646 | offset += lengthInChunk; |
| 647 | length -= lengthInChunk; |
| 648 | } |
| 649 | |
| 650 | co_await folly::collectAll(tasks.begin(), tasks.end()); |
| 651 | } |
| 652 | |
| 653 | TEST_F(TestMetaClient, testRemoveChunksBatchSize) { |
| 654 | folly::coro::blockingWait([&]() -> CoTask<void> { |
no test coverage detected