Merge changes I7ec850b5,I62aa8c7b
* changes: libsnapshot: Use pointers instead of references in ICowOpIter. libsnapshot: Move BLOCK_SZ to snapuserd.
This commit is contained in:
commit
c274088e5c
15 changed files with 146 additions and 147 deletions
|
|
@ -28,9 +28,6 @@ static constexpr uint32_t kCowVersionMinor = 0;
|
|||
|
||||
static constexpr uint32_t kCowVersionManifest = 2;
|
||||
|
||||
static constexpr size_t BLOCK_SZ = 4096;
|
||||
static constexpr size_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SZ) - 1);
|
||||
|
||||
// This header appears as the first sequence of bytes in the COW. All fields
|
||||
// in the layout are little-endian encoded. The on-disk layout is:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -63,7 +63,9 @@ class ICowReader {
|
|||
//
|
||||
// Partial reads are not possible unless |buffer_size| is less than the
|
||||
// operation block size.
|
||||
virtual ssize_t ReadData(const CowOperation& op, void* buffer, size_t buffer_size,
|
||||
//
|
||||
// The operation pointer must derive from ICowOpIter::Get().
|
||||
virtual ssize_t ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
|
||||
size_t ignore_bytes = 0) = 0;
|
||||
};
|
||||
|
||||
|
|
@ -77,7 +79,7 @@ class ICowOpIter {
|
|||
virtual bool AtEnd() = 0;
|
||||
|
||||
// Read the current operation.
|
||||
virtual const CowOperation& Get() = 0;
|
||||
virtual const CowOperation* Get() = 0;
|
||||
|
||||
// Advance to the next item.
|
||||
virtual void Next() = 0;
|
||||
|
|
@ -121,7 +123,7 @@ class CowReader final : public ICowReader {
|
|||
std::unique_ptr<ICowOpIter> GetRevMergeOpIter(bool ignore_progress = false) override;
|
||||
std::unique_ptr<ICowOpIter> GetMergeOpIter(bool ignore_progress = false) override;
|
||||
|
||||
ssize_t ReadData(const CowOperation& op, void* buffer, size_t buffer_size,
|
||||
ssize_t ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
|
||||
size_t ignore_bytes = 0) override;
|
||||
|
||||
CowHeader& GetHeader() override { return header_; }
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ class CowTest : public ::testing::Test {
|
|||
};
|
||||
|
||||
// Helper to check read sizes.
|
||||
static inline bool ReadData(CowReader& reader, const CowOperation& op, void* buffer, size_t size) {
|
||||
static inline bool ReadData(CowReader& reader, const CowOperation* op, void* buffer, size_t size) {
|
||||
return reader.ReadData(op, buffer, size) == size;
|
||||
}
|
||||
|
||||
|
|
@ -80,7 +80,7 @@ TEST_F(CowTest, CopyContiguous) {
|
|||
|
||||
size_t i = 0;
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
|
|
@ -126,7 +126,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
|
|
@ -138,18 +138,18 @@ TEST_F(CowTest, ReadWrite) {
|
|||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
// Note: the zero operation gets split into two blocks.
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
|
@ -160,7 +160,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
|
|
@ -205,7 +205,7 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
|
|
@ -217,19 +217,19 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowXorOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_EQ(op->source, 98314); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
// Note: the zero operation gets split into two blocks.
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
|
@ -240,7 +240,7 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressNone);
|
||||
|
|
@ -274,7 +274,7 @@ TEST_F(CowTest, CompressGz) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
|
|
@ -282,7 +282,7 @@ TEST_F(CowTest, CompressGz) {
|
|||
ASSERT_EQ(op->compression, kCowCompressGz);
|
||||
ASSERT_EQ(op->data_length, 56); // compressed!
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
|
|
@ -329,14 +329,14 @@ TEST_P(CompressionTest, ThreadedBatchWrites) {
|
|||
|
||||
int total_blocks = 0;
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
|
||||
if (op->type == kCowXorOp) {
|
||||
total_blocks += 1;
|
||||
std::string sink(xor_data.size(), '\0');
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_EQ(op->source, 98314); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, xor_data);
|
||||
}
|
||||
|
||||
|
|
@ -345,19 +345,19 @@ TEST_P(CompressionTest, ThreadedBatchWrites) {
|
|||
if (op->new_block == 100) {
|
||||
data.resize(options.block_size);
|
||||
std::string sink(data.size(), '\0');
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink.size(), data.size());
|
||||
ASSERT_EQ(sink, data);
|
||||
}
|
||||
if (op->new_block == 6000) {
|
||||
data2.resize(options.block_size);
|
||||
std::string sink(data2.size(), '\0');
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
}
|
||||
if (op->new_block == 9000) {
|
||||
std::string sink(data3.size(), '\0');
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data3);
|
||||
}
|
||||
}
|
||||
|
|
@ -403,25 +403,25 @@ TEST_P(CompressionTest, NoBatchWrites) {
|
|||
|
||||
int total_blocks = 0;
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
|
||||
if (op->type == kCowReplaceOp) {
|
||||
total_blocks += 1;
|
||||
if (op->new_block == 50) {
|
||||
data.resize(options.block_size);
|
||||
std::string sink(data.size(), '\0');
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
}
|
||||
if (op->new_block == 3000) {
|
||||
data2.resize(options.block_size);
|
||||
std::string sink(data2.size(), '\0');
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
}
|
||||
if (op->new_block == 5000) {
|
||||
std::string sink(data3.size(), '\0');
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data3);
|
||||
}
|
||||
}
|
||||
|
|
@ -519,7 +519,7 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
auto iter = reader.GetOpIter();
|
||||
ASSERT_NE(iter, nullptr);
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
|
|
@ -527,30 +527,30 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
ASSERT_EQ(op->compression, kCowCompressGz);
|
||||
ASSERT_EQ(op->data_length, 56); // compressed!
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
sink = {};
|
||||
sink.resize(data2.size(), '\0');
|
||||
ASSERT_EQ(op->compression, kCowCompressGz);
|
||||
ASSERT_EQ(op->data_length, 41); // compressed!
|
||||
ASSERT_EQ(op->new_block, 51);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
|
|
@ -585,11 +585,11 @@ TEST_F(CowTest, CompressTwoBlocks) {
|
|||
|
||||
std::string sink(options.block_size, '\0');
|
||||
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->compression, kCowCompressGz);
|
||||
ASSERT_EQ(op->new_block, 51);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
}
|
||||
|
||||
TEST_F(CowTest, GetSize) {
|
||||
|
|
@ -659,9 +659,9 @@ TEST_F(CowTest, AppendLabelSmall) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
iter->Next();
|
||||
|
|
@ -669,16 +669,16 @@ TEST_F(CowTest, AppendLabelSmall) {
|
|||
sink.resize(data2.size(), '\0');
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 3);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
|
||||
iter->Next();
|
||||
|
|
@ -722,14 +722,14 @@ TEST_F(CowTest, AppendLabelMissing) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 0);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
|
@ -780,7 +780,7 @@ TEST_F(CowTest, AppendExtendedCorrupted) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 5);
|
||||
|
||||
|
|
@ -831,9 +831,9 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data.substr(0, options.block_size));
|
||||
|
||||
iter->Next();
|
||||
|
|
@ -841,33 +841,33 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
sink.resize(options.block_size, '\0');
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data.substr(options.block_size, 2 * options.block_size));
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 4);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 5);
|
||||
|
||||
|
|
@ -912,59 +912,59 @@ TEST_F(CowTest, ClusterTest) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data.substr(0, options.block_size));
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 4);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 5);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 6);
|
||||
|
||||
|
|
@ -1011,22 +1011,22 @@ TEST_F(CowTest, ClusterAppendTest) {
|
|||
ASSERT_NE(iter, nullptr);
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = &iter->Get();
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(op->source, 50);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, *op, sink.data(), sink.size()));
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = &iter->Get();
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
|
@ -1066,7 +1066,7 @@ AssertionResult WriteDataBlock(CowWriter* writer, uint64_t new_block, std::strin
|
|||
return AssertionSuccess();
|
||||
}
|
||||
|
||||
AssertionResult CompareDataBlock(CowReader* reader, const CowOperation& op,
|
||||
AssertionResult CompareDataBlock(CowReader* reader, const CowOperation* op,
|
||||
const std::string& data) {
|
||||
const auto& header = reader->GetHeader();
|
||||
|
||||
|
|
@ -1124,12 +1124,12 @@ TEST_F(CowTest, ResumeMidCluster) {
|
|||
num_in_cluster++;
|
||||
max_in_cluster = std::max(max_in_cluster, num_in_cluster);
|
||||
|
||||
if (op.type == kCowReplaceOp) {
|
||||
if (op->type == kCowReplaceOp) {
|
||||
num_replace++;
|
||||
|
||||
ASSERT_EQ(op.new_block, num_replace);
|
||||
ASSERT_EQ(op->new_block, num_replace);
|
||||
ASSERT_TRUE(CompareDataBlock(&reader, op, "Block " + std::to_string(num_replace)));
|
||||
} else if (op.type == kCowClusterOp) {
|
||||
} else if (op->type == kCowClusterOp) {
|
||||
num_in_cluster = 0;
|
||||
num_clusters++;
|
||||
}
|
||||
|
|
@ -1185,12 +1185,12 @@ TEST_F(CowTest, ResumeEndCluster) {
|
|||
num_in_cluster++;
|
||||
max_in_cluster = std::max(max_in_cluster, num_in_cluster);
|
||||
|
||||
if (op.type == kCowReplaceOp) {
|
||||
if (op->type == kCowReplaceOp) {
|
||||
num_replace++;
|
||||
|
||||
ASSERT_EQ(op.new_block, num_replace);
|
||||
ASSERT_EQ(op->new_block, num_replace);
|
||||
ASSERT_TRUE(CompareDataBlock(&reader, op, "Block " + std::to_string(num_replace)));
|
||||
} else if (op.type == kCowClusterOp) {
|
||||
} else if (op->type == kCowClusterOp) {
|
||||
num_in_cluster = 0;
|
||||
num_clusters++;
|
||||
}
|
||||
|
|
@ -1236,12 +1236,12 @@ TEST_F(CowTest, DeleteMidCluster) {
|
|||
|
||||
num_in_cluster++;
|
||||
max_in_cluster = std::max(max_in_cluster, num_in_cluster);
|
||||
if (op.type == kCowReplaceOp) {
|
||||
if (op->type == kCowReplaceOp) {
|
||||
num_replace++;
|
||||
|
||||
ASSERT_EQ(op.new_block, num_replace);
|
||||
ASSERT_EQ(op->new_block, num_replace);
|
||||
ASSERT_TRUE(CompareDataBlock(&reader, op, "Block " + std::to_string(num_replace)));
|
||||
} else if (op.type == kCowClusterOp) {
|
||||
} else if (op->type == kCowClusterOp) {
|
||||
num_in_cluster = 0;
|
||||
num_clusters++;
|
||||
}
|
||||
|
|
@ -1278,7 +1278,7 @@ TEST_F(CowTest, BigSeqOp) {
|
|||
ASSERT_TRUE(!iter->AtEnd());
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, seq_len - i);
|
||||
ASSERT_EQ(op->new_block, seq_len - i);
|
||||
|
||||
iter->Next();
|
||||
}
|
||||
|
|
@ -1345,7 +1345,7 @@ TEST_F(CowTest, ResumeSeqOp) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, expected_block);
|
||||
ASSERT_EQ(op->new_block, expected_block);
|
||||
|
||||
iter->Next();
|
||||
expected_block--;
|
||||
|
|
@ -1395,7 +1395,7 @@ TEST_F(CowTest, RevMergeOpItrTest) {
|
|||
while (!iter->AtEnd() && expected_new_block != revMergeOpSequence.end()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, *expected_new_block);
|
||||
ASSERT_EQ(op->new_block, *expected_new_block);
|
||||
|
||||
iter->Next();
|
||||
expected_new_block++;
|
||||
|
|
@ -1444,7 +1444,7 @@ TEST_F(CowTest, LegacyRevMergeOpItrTest) {
|
|||
while (!iter->AtEnd() && expected_new_block != revMergeOpSequence.end()) {
|
||||
const auto& op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op.new_block, *expected_new_block);
|
||||
ASSERT_EQ(op->new_block, *expected_new_block);
|
||||
|
||||
iter->Next();
|
||||
expected_new_block++;
|
||||
|
|
|
|||
|
|
@ -57,8 +57,6 @@ std::ostream& operator<<(std::ostream& os, CowOperation const& op) {
|
|||
os << "data_length:" << op.data_length << ",\t";
|
||||
os << "new_block:" << op.new_block << ",\t";
|
||||
os << "source:" << op.source;
|
||||
if (op.type == kCowXorOp)
|
||||
os << " (block:" << op.source / BLOCK_SZ << " offset:" << op.source % BLOCK_SZ << ")";
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -508,37 +508,37 @@ bool CowReader::PrepMergeOps() {
|
|||
|
||||
bool CowReader::VerifyMergeOps() {
|
||||
auto itr = GetMergeOpIter(true);
|
||||
std::unordered_map<uint64_t, CowOperation> overwritten_blocks;
|
||||
std::unordered_map<uint64_t, const CowOperation*> overwritten_blocks;
|
||||
while (!itr->AtEnd()) {
|
||||
CowOperation op = itr->Get();
|
||||
const auto& op = itr->Get();
|
||||
uint64_t block;
|
||||
bool offset;
|
||||
if (op.type == kCowCopyOp) {
|
||||
block = op.source;
|
||||
if (op->type == kCowCopyOp) {
|
||||
block = op->source;
|
||||
offset = false;
|
||||
} else if (op.type == kCowXorOp) {
|
||||
block = op.source / BLOCK_SZ;
|
||||
offset = (op.source % BLOCK_SZ) != 0;
|
||||
} else if (op->type == kCowXorOp) {
|
||||
block = op->source / header_.block_size;
|
||||
offset = (op->source % header_.block_size) != 0;
|
||||
} else {
|
||||
itr->Next();
|
||||
continue;
|
||||
}
|
||||
|
||||
CowOperation* overwrite = nullptr;
|
||||
const CowOperation* overwrite = nullptr;
|
||||
if (overwritten_blocks.count(block)) {
|
||||
overwrite = &overwritten_blocks[block];
|
||||
overwrite = overwritten_blocks[block];
|
||||
LOG(ERROR) << "Invalid Sequence! Block needed for op:\n"
|
||||
<< op << "\noverwritten by previously merged op:\n"
|
||||
<< *overwrite;
|
||||
}
|
||||
if (offset && overwritten_blocks.count(block + 1)) {
|
||||
overwrite = &overwritten_blocks[block + 1];
|
||||
overwrite = overwritten_blocks[block + 1];
|
||||
LOG(ERROR) << "Invalid Sequence! Block needed for op:\n"
|
||||
<< op << "\noverwritten by previously merged op:\n"
|
||||
<< *overwrite;
|
||||
}
|
||||
if (overwrite != nullptr) return false;
|
||||
overwritten_blocks[op.new_block] = op;
|
||||
overwritten_blocks[op->new_block] = op;
|
||||
itr->Next();
|
||||
}
|
||||
return true;
|
||||
|
|
@ -561,7 +561,7 @@ class CowOpIter final : public ICowOpIter {
|
|||
CowOpIter(std::shared_ptr<std::vector<CowOperation>>& ops, uint64_t start);
|
||||
|
||||
bool AtEnd() override;
|
||||
const CowOperation& Get() override;
|
||||
const CowOperation* Get() override;
|
||||
void Next() override;
|
||||
|
||||
void Prev() override;
|
||||
|
|
@ -595,9 +595,9 @@ void CowOpIter::Next() {
|
|||
op_iter_++;
|
||||
}
|
||||
|
||||
const CowOperation& CowOpIter::Get() {
|
||||
const CowOperation* CowOpIter::Get() {
|
||||
CHECK(!AtEnd());
|
||||
return (*op_iter_);
|
||||
return &(*op_iter_);
|
||||
}
|
||||
|
||||
class CowRevMergeOpIter final : public ICowOpIter {
|
||||
|
|
@ -606,7 +606,7 @@ class CowRevMergeOpIter final : public ICowOpIter {
|
|||
std::shared_ptr<std::vector<int>> block_pos_index, uint64_t start);
|
||||
|
||||
bool AtEnd() override;
|
||||
const CowOperation& Get() override;
|
||||
const CowOperation* Get() override;
|
||||
void Next() override;
|
||||
|
||||
void Prev() override;
|
||||
|
|
@ -625,7 +625,7 @@ class CowMergeOpIter final : public ICowOpIter {
|
|||
std::shared_ptr<std::vector<int>> block_pos_index, uint64_t start);
|
||||
|
||||
bool AtEnd() override;
|
||||
const CowOperation& Get() override;
|
||||
const CowOperation* Get() override;
|
||||
void Next() override;
|
||||
|
||||
void Prev() override;
|
||||
|
|
@ -664,9 +664,9 @@ void CowMergeOpIter::Next() {
|
|||
block_iter_++;
|
||||
}
|
||||
|
||||
const CowOperation& CowMergeOpIter::Get() {
|
||||
const CowOperation* CowMergeOpIter::Get() {
|
||||
CHECK(!AtEnd());
|
||||
return ops_->data()[*block_iter_];
|
||||
return &ops_->data()[*block_iter_];
|
||||
}
|
||||
|
||||
CowRevMergeOpIter::CowRevMergeOpIter(std::shared_ptr<std::vector<CowOperation>> ops,
|
||||
|
|
@ -696,9 +696,9 @@ void CowRevMergeOpIter::Next() {
|
|||
block_riter_++;
|
||||
}
|
||||
|
||||
const CowOperation& CowRevMergeOpIter::Get() {
|
||||
const CowOperation* CowRevMergeOpIter::Get() {
|
||||
CHECK(!AtEnd());
|
||||
return ops_->data()[*block_riter_];
|
||||
return &ops_->data()[*block_riter_];
|
||||
}
|
||||
|
||||
std::unique_ptr<ICowOpIter> CowReader::GetOpIter(bool merge_progress) {
|
||||
|
|
@ -765,10 +765,10 @@ class CowDataStream final : public IByteStream {
|
|||
size_t remaining_;
|
||||
};
|
||||
|
||||
ssize_t CowReader::ReadData(const CowOperation& op, void* buffer, size_t buffer_size,
|
||||
ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_size,
|
||||
size_t ignore_bytes) {
|
||||
std::unique_ptr<IDecompressor> decompressor;
|
||||
switch (op.compression) {
|
||||
switch (op->compression) {
|
||||
case kCowCompressNone:
|
||||
break;
|
||||
case kCowCompressGz:
|
||||
|
|
@ -778,28 +778,28 @@ ssize_t CowReader::ReadData(const CowOperation& op, void* buffer, size_t buffer_
|
|||
decompressor = IDecompressor::Brotli();
|
||||
break;
|
||||
case kCowCompressLz4:
|
||||
if (header_.block_size != op.data_length) {
|
||||
if (header_.block_size != op->data_length) {
|
||||
decompressor = IDecompressor::Lz4();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
LOG(ERROR) << "Unknown compression type: " << op.compression;
|
||||
LOG(ERROR) << "Unknown compression type: " << op->compression;
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint64_t offset;
|
||||
if (op.type == kCowXorOp) {
|
||||
offset = data_loc_->at(op.new_block);
|
||||
if (op->type == kCowXorOp) {
|
||||
offset = data_loc_->at(op->new_block);
|
||||
} else {
|
||||
offset = op.source;
|
||||
offset = op->source;
|
||||
}
|
||||
|
||||
if (!decompressor) {
|
||||
CowDataStream stream(this, offset + ignore_bytes, op.data_length - ignore_bytes);
|
||||
CowDataStream stream(this, offset + ignore_bytes, op->data_length - ignore_bytes);
|
||||
return stream.ReadFully(buffer, buffer_size);
|
||||
}
|
||||
|
||||
CowDataStream stream(this, offset, op.data_length);
|
||||
CowDataStream stream(this, offset, op->data_length);
|
||||
decompressor->set_stream(&stream);
|
||||
return decompressor->Decompress(buffer, buffer_size, header_.block_size, ignore_bytes);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,7 +407,7 @@ bool CowWriter::OpenForAppend(uint64_t label) {
|
|||
auto iter = reader->GetOpIter();
|
||||
|
||||
while (!iter->AtEnd()) {
|
||||
AddOperation(iter->Get());
|
||||
AddOperation(*iter->Get());
|
||||
iter->Next();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,19 +64,19 @@ struct Options {
|
|||
bool include_merged;
|
||||
};
|
||||
|
||||
static void ShowBad(CowReader& reader, const struct CowOperation& op) {
|
||||
static void ShowBad(CowReader& reader, const struct CowOperation* op) {
|
||||
size_t count;
|
||||
auto buffer = std::make_unique<uint8_t[]>(op.data_length);
|
||||
auto buffer = std::make_unique<uint8_t[]>(op->data_length);
|
||||
|
||||
if (!reader.GetRawBytes(op.source, buffer.get(), op.data_length, &count)) {
|
||||
if (!reader.GetRawBytes(op->source, buffer.get(), op->data_length, &count)) {
|
||||
std::cerr << "Failed to read at all!\n";
|
||||
} else {
|
||||
std::cout << "The Block data is:\n";
|
||||
for (int i = 0; i < op.data_length; i++) {
|
||||
for (int i = 0; i < op->data_length; i++) {
|
||||
std::cout << std::hex << (int)buffer[i];
|
||||
}
|
||||
std::cout << std::dec << "\n\n";
|
||||
if (op.data_length >= sizeof(CowOperation)) {
|
||||
if (op->data_length >= sizeof(CowOperation)) {
|
||||
std::cout << "The start, as an op, would be " << *(CowOperation*)buffer.get() << "\n";
|
||||
}
|
||||
}
|
||||
|
|
@ -145,29 +145,29 @@ static bool Inspect(const std::string& path, Options opt) {
|
|||
bool success = true;
|
||||
uint64_t xor_ops = 0, copy_ops = 0, replace_ops = 0, zero_ops = 0;
|
||||
while (!iter->AtEnd()) {
|
||||
const CowOperation& op = iter->Get();
|
||||
const CowOperation* op = iter->Get();
|
||||
|
||||
if (!opt.silent && opt.show_ops) std::cout << op << "\n";
|
||||
if (!opt.silent && opt.show_ops) std::cout << *op << "\n";
|
||||
|
||||
if (opt.decompress && op.type == kCowReplaceOp && op.compression != kCowCompressNone) {
|
||||
if (opt.decompress && op->type == kCowReplaceOp && op->compression != kCowCompressNone) {
|
||||
if (reader.ReadData(op, buffer.data(), buffer.size()) < 0) {
|
||||
std::cerr << "Failed to decompress for :" << op << "\n";
|
||||
std::cerr << "Failed to decompress for :" << *op << "\n";
|
||||
success = false;
|
||||
if (opt.show_bad) ShowBad(reader, op);
|
||||
}
|
||||
}
|
||||
|
||||
if (op.type == kCowSequenceOp && opt.show_seq) {
|
||||
if (op->type == kCowSequenceOp && opt.show_seq) {
|
||||
size_t read;
|
||||
std::vector<uint32_t> merge_op_blocks;
|
||||
size_t seq_len = op.data_length / sizeof(uint32_t);
|
||||
size_t seq_len = op->data_length / sizeof(uint32_t);
|
||||
merge_op_blocks.resize(seq_len);
|
||||
if (!reader.GetRawBytes(op.source, merge_op_blocks.data(), op.data_length, &read)) {
|
||||
if (!reader.GetRawBytes(op->source, merge_op_blocks.data(), op->data_length, &read)) {
|
||||
PLOG(ERROR) << "Failed to read sequence op!";
|
||||
return false;
|
||||
}
|
||||
if (!opt.silent) {
|
||||
std::cout << "Sequence for " << op << " is :\n";
|
||||
std::cout << "Sequence for " << *op << " is :\n";
|
||||
for (size_t i = 0; i < seq_len; i++) {
|
||||
std::cout << std::setfill('0') << std::setw(6) << merge_op_blocks[i] << ", ";
|
||||
if ((i + 1) % 10 == 0 || i + 1 == seq_len) std::cout << "\n";
|
||||
|
|
@ -175,13 +175,13 @@ static bool Inspect(const std::string& path, Options opt) {
|
|||
}
|
||||
}
|
||||
|
||||
if (op.type == kCowCopyOp) {
|
||||
if (op->type == kCowCopyOp) {
|
||||
copy_ops++;
|
||||
} else if (op.type == kCowReplaceOp) {
|
||||
} else if (op->type == kCowReplaceOp) {
|
||||
replace_ops++;
|
||||
} else if (op.type == kCowZeroOp) {
|
||||
} else if (op->type == kCowZeroOp) {
|
||||
zero_ops++;
|
||||
} else if (op.type == kCowXorOp) {
|
||||
} else if (op->type == kCowXorOp) {
|
||||
xor_ops++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ bool CompressedSnapshotReader::SetCow(std::unique_ptr<CowReader>&& cow) {
|
|||
// Populate the operation map.
|
||||
op_iter_ = cow_->GetOpIter();
|
||||
while (!op_iter_->AtEnd()) {
|
||||
const CowOperation* op = &op_iter_->Get();
|
||||
const CowOperation* op = op_iter_->Get();
|
||||
if (IsMetadataOp(*op)) {
|
||||
op_iter_->Next();
|
||||
continue;
|
||||
|
|
@ -205,7 +205,7 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
|
|||
} else if (op->type == kCowZeroOp) {
|
||||
memset(buffer, 0, bytes_to_read);
|
||||
} else if (op->type == kCowReplaceOp) {
|
||||
if (cow_->ReadData(*op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
|
||||
if (cow_->ReadData(op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
|
||||
LOG(ERROR) << "CompressedSnapshotReader failed to read replace op";
|
||||
errno = EIO;
|
||||
return -1;
|
||||
|
|
@ -226,7 +226,7 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (cow_->ReadData(*op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
|
||||
if (cow_->ReadData(op, buffer, bytes_to_read, start_offset) < bytes_to_read) {
|
||||
LOG(ERROR) << "CompressedSnapshotReader failed to read xor op";
|
||||
errno = EIO;
|
||||
return -1;
|
||||
|
|
|
|||
|
|
@ -391,7 +391,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
memset(de_ptr.get(), 0, (exceptions_per_area_ * sizeof(struct disk_exception)));
|
||||
|
||||
while (!cowop_rm_iter->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_rm_iter->Get();
|
||||
const CowOperation* cow_op = cowop_rm_iter->Get();
|
||||
struct disk_exception* de =
|
||||
reinterpret_cast<struct disk_exception*>((char*)de_ptr.get() + offset);
|
||||
|
||||
|
|
@ -459,7 +459,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
|
||||
while (!cowop_rm_iter->AtEnd()) {
|
||||
do {
|
||||
const CowOperation* cow_op = &cowop_rm_iter->Get();
|
||||
const CowOperation* cow_op = cowop_rm_iter->Get();
|
||||
|
||||
// We have two cases specific cases:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ bool WorkerThread::ProcessReplaceOp(const CowOperation* cow_op) {
|
|||
SNAP_LOG(ERROR) << "No space in buffer sink";
|
||||
return false;
|
||||
}
|
||||
ssize_t rv = reader_->ReadData(*cow_op, buffer, BLOCK_SZ);
|
||||
ssize_t rv = reader_->ReadData(cow_op, buffer, BLOCK_SZ);
|
||||
if (rv != BLOCK_SZ) {
|
||||
SNAP_LOG(ERROR) << "ProcessReplaceOp failed for block " << cow_op->new_block
|
||||
<< ", return = " << rv;
|
||||
|
|
|
|||
|
|
@ -41,6 +41,9 @@ static constexpr uint32_t SNAPSHOT_VALID = 1;
|
|||
*/
|
||||
static constexpr uint32_t SECTOR_SHIFT = 9;
|
||||
|
||||
static constexpr size_t BLOCK_SZ = 4096;
|
||||
static constexpr size_t BLOCK_SHIFT = (__builtin_ffs(BLOCK_SZ) - 1);
|
||||
|
||||
typedef __u64 sector_t;
|
||||
typedef sector_t chunk_t;
|
||||
|
||||
|
|
|
|||
|
|
@ -186,7 +186,7 @@ bool SnapshotHandler::ReadMetadata() {
|
|||
size_t copy_ops = 0, replace_ops = 0, zero_ops = 0, xor_ops = 0;
|
||||
|
||||
while (!cowop_iter->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_iter->Get();
|
||||
const CowOperation* cow_op = cowop_iter->Get();
|
||||
|
||||
if (cow_op->type == kCowCopyOp) {
|
||||
copy_ops += 1;
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ bool Worker::ProcessReplaceOp(const CowOperation* cow_op) {
|
|||
SNAP_LOG(ERROR) << "ProcessReplaceOp failed to allocate buffer";
|
||||
return false;
|
||||
}
|
||||
if (!reader_->ReadData(*cow_op, buffer, BLOCK_SZ)) {
|
||||
if (!reader_->ReadData(cow_op, buffer, BLOCK_SZ)) {
|
||||
SNAP_LOG(ERROR) << "ProcessReplaceOp failed for block " << cow_op->new_block;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ bool Worker::ProcessXorOp(const CowOperation* cow_op) {
|
|||
<< actual;
|
||||
return false;
|
||||
}
|
||||
ssize_t size = reader_->ReadData(*cow_op, buffer, BLOCK_SZ);
|
||||
ssize_t size = reader_->ReadData(cow_op, buffer, BLOCK_SZ);
|
||||
if (size != BLOCK_SZ) {
|
||||
SNAP_LOG(ERROR) << "ProcessXorOp failed for block " << cow_op->new_block
|
||||
<< ", return value: " << size;
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ int Worker::PrepareMerge(uint64_t* source_offset, int* pending_ops,
|
|||
|
||||
do {
|
||||
if (!cowop_iter_->AtEnd() && num_ops) {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
const CowOperation* cow_op = cowop_iter_->Get();
|
||||
if (checkOrderedOp && !IsOrderedOp(*cow_op)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -46,7 +46,7 @@ int Worker::PrepareMerge(uint64_t* source_offset, int* pending_ops,
|
|||
nr_consecutive = 1;
|
||||
|
||||
while (!cowop_iter_->AtEnd() && num_ops) {
|
||||
const CowOperation* op = &cowop_iter_->Get();
|
||||
const CowOperation* op = cowop_iter_->Get();
|
||||
if (checkOrderedOp && !IsOrderedOp(*op)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -181,7 +181,7 @@ bool Worker::MergeOrderedOpsAsync() {
|
|||
SNAP_LOG(INFO) << "MergeOrderedOpsAsync started....";
|
||||
|
||||
while (!cowop_iter_->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
const CowOperation* cow_op = cowop_iter_->Get();
|
||||
if (!IsOrderedOp(*cow_op)) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -362,7 +362,7 @@ bool Worker::MergeOrderedOps() {
|
|||
SNAP_LOG(INFO) << "MergeOrderedOps started....";
|
||||
|
||||
while (!cowop_iter_->AtEnd()) {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
const CowOperation* cow_op = cowop_iter_->Get();
|
||||
if (!IsOrderedOp(*cow_op)) {
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -492,7 +492,7 @@ bool ReadAhead::ReadXorData(size_t block_index, size_t xor_op_index,
|
|||
<< xor_op->new_block;
|
||||
return false;
|
||||
}
|
||||
if (ssize_t rv = reader_->ReadData(*xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
|
||||
if (ssize_t rv = reader_->ReadData(xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
|
||||
SNAP_LOG(ERROR)
|
||||
<< " ReadAhead - XorOp Read failed for block: " << xor_op->new_block
|
||||
<< ", return value: " << rv;
|
||||
|
|
@ -592,7 +592,7 @@ bool ReadAhead::ReadAheadSyncIO() {
|
|||
SNAP_LOG(ERROR) << "ReadAhead - failed to allocate buffer";
|
||||
return false;
|
||||
}
|
||||
if (ssize_t rv = reader_->ReadData(*xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
|
||||
if (ssize_t rv = reader_->ReadData(xor_op, buffer, BLOCK_SZ); rv != BLOCK_SZ) {
|
||||
SNAP_LOG(ERROR)
|
||||
<< " ReadAhead - XorOp Read failed for block: " << xor_op->new_block
|
||||
<< ", return value: " << rv;
|
||||
|
|
@ -834,8 +834,7 @@ void ReadAhead::RAResetIter(uint64_t num_blocks) {
|
|||
}
|
||||
|
||||
const CowOperation* ReadAhead::GetRAOpIter() {
|
||||
const CowOperation* cow_op = &cowop_iter_->Get();
|
||||
return cow_op;
|
||||
return cowop_iter_->Get();
|
||||
}
|
||||
|
||||
void ReadAhead::InitializeBuffer() {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue