Merge "Shove CowOperation type into source_info" into main
This commit is contained in:
commit
240f7084be
17 changed files with 179 additions and 165 deletions
|
@ -19,6 +19,7 @@
|
|||
#include <limits>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
|
||||
namespace android {
|
||||
namespace snapshot {
|
||||
|
@ -194,11 +195,12 @@ struct CowOperationV2 {
|
|||
uint64_t source;
|
||||
} __attribute__((packed));
|
||||
|
||||
static constexpr uint64_t kCowOpSourceInfoDataMask = (1ULL << 48) - 1;
|
||||
static constexpr uint64_t kCowOpSourceInfoTypeBit = 60;
|
||||
static constexpr uint64_t kCowOpSourceInfoTypeNumBits = 4;
|
||||
static constexpr uint64_t kCowOpSourceInfoTypeMask = (1ULL << kCowOpSourceInfoTypeNumBits) - 1;
|
||||
// The on disk format of cow (currently == CowOperation)
|
||||
struct CowOperationV3 {
|
||||
// The operation code (see the constants and structures below).
|
||||
CowOperationType type;
|
||||
|
||||
// If this operation reads from the data section of the COW, this contains
|
||||
// the length.
|
||||
uint16_t data_length;
|
||||
|
@ -206,6 +208,10 @@ struct CowOperationV3 {
|
|||
// The block of data in the new image that this operation modifies.
|
||||
uint32_t new_block;
|
||||
|
||||
// source_info with have the following layout
|
||||
// |---4 bits ---| ---12 bits---| --- 48 bits ---|
|
||||
// |--- type --- | -- unused -- | --- source --- |
|
||||
//
|
||||
// The value of |source| depends on the operation code.
|
||||
//
|
||||
// CopyOp: a 32-bit block location in the source image.
|
||||
|
@ -217,9 +223,26 @@ struct CowOperationV3 {
|
|||
// For ops other than Label:
|
||||
// Bits 47-62 are reserved and must be zero.
|
||||
// A block is compressed if it’s data is < block_sz
|
||||
uint64_t source_info;
|
||||
uint64_t source_info_;
|
||||
constexpr uint64_t source() const { return source_info_ & kCowOpSourceInfoDataMask; }
|
||||
constexpr void set_source(uint64_t source) {
|
||||
source_info_ |= source & kCowOpSourceInfoDataMask;
|
||||
}
|
||||
constexpr CowOperationType type() const {
|
||||
// this is a mask to grab the first 4 bits of a 64 bit integer
|
||||
const auto type = (source_info_ >> kCowOpSourceInfoTypeBit) & kCowOpSourceInfoTypeMask;
|
||||
return static_cast<CowOperationType>(type);
|
||||
}
|
||||
constexpr void set_type(CowOperationType type) {
|
||||
source_info_ |= (static_cast<uint64_t>(type) & kCowOpSourceInfoTypeMask)
|
||||
<< kCowOpSourceInfoTypeBit;
|
||||
}
|
||||
} __attribute__((packed));
|
||||
|
||||
// Ensure that getters/setters added to CowOperationV3 does not increases size
|
||||
// of CowOperationV3 struct(no virtual method tables added).
|
||||
static_assert(std::is_trivially_copyable_v<CowOperationV3>);
|
||||
static_assert(std::is_standard_layout_v<CowOperationV3>);
|
||||
static_assert(sizeof(CowOperationV2) == sizeof(CowFooterOperation));
|
||||
|
||||
enum CowCompressionAlgorithm : uint8_t {
|
||||
|
@ -238,12 +261,6 @@ static constexpr uint8_t kCowReadAheadNotStarted = 0;
|
|||
static constexpr uint8_t kCowReadAheadInProgress = 1;
|
||||
static constexpr uint8_t kCowReadAheadDone = 2;
|
||||
|
||||
static constexpr uint64_t kCowOpSourceInfoDataMask = (1ULL << 48) - 1;
|
||||
|
||||
static inline uint64_t GetCowOpSourceInfoData(const CowOperation& op) {
|
||||
return op.source_info & kCowOpSourceInfoDataMask;
|
||||
}
|
||||
|
||||
static constexpr off_t GetSequenceOffset(const CowHeaderV3& header) {
|
||||
return header.prefix.header_size + header.buffer_size;
|
||||
}
|
||||
|
@ -284,7 +301,7 @@ static constexpr uint64_t BUFFER_REGION_DEFAULT_SIZE = (1ULL << 21);
|
|||
|
||||
std::ostream& operator<<(std::ostream& os, CowOperationV2 const& arg);
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CowOperation const& arg);
|
||||
std::ostream& operator<<(std::ostream& os, CowOperationV3 const& arg);
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, ResumePoint const& arg);
|
||||
|
||||
|
|
|
@ -80,22 +80,21 @@ std::ostream& operator<<(std::ostream& os, CowOperationV2 const& op) {
|
|||
return os;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, CowOperation const& op) {
|
||||
std::ostream& operator<<(std::ostream& os, CowOperationV3 const& op) {
|
||||
os << "CowOperation(";
|
||||
EmitCowTypeString(os, op.type);
|
||||
if (op.type == kCowReplaceOp || op.type == kCowXorOp || op.type == kCowSequenceOp) {
|
||||
EmitCowTypeString(os, op.type());
|
||||
if (op.type() == kCowReplaceOp || op.type() == kCowXorOp || op.type() == kCowSequenceOp) {
|
||||
os << ", data_length:" << op.data_length;
|
||||
}
|
||||
if (op.type != kCowClusterOp && op.type != kCowSequenceOp && op.type != kCowLabelOp) {
|
||||
if (op.type() != kCowClusterOp && op.type() != kCowSequenceOp && op.type() != kCowLabelOp) {
|
||||
os << ", new_block:" << op.new_block;
|
||||
}
|
||||
if (op.type == kCowXorOp || op.type == kCowReplaceOp || op.type == kCowCopyOp) {
|
||||
os << ", source:" << (op.source_info & kCowOpSourceInfoDataMask);
|
||||
} else if (op.type == kCowClusterOp) {
|
||||
os << ", cluster_data:" << (op.source_info & kCowOpSourceInfoDataMask);
|
||||
} else {
|
||||
os << ", label:0x" << android::base::StringPrintf("%" PRIx64, op.source_info);
|
||||
if (op.type() == kCowXorOp || op.type() == kCowReplaceOp || op.type() == kCowCopyOp) {
|
||||
os << ", source:" << op.source();
|
||||
} else if (op.type() == kCowClusterOp) {
|
||||
os << ", cluster_data:" << op.source();
|
||||
}
|
||||
// V3 op stores resume points in header, so CowOp can never be Label.
|
||||
os << ")";
|
||||
return os;
|
||||
}
|
||||
|
@ -126,7 +125,7 @@ int64_t GetNextDataOffset(const CowOperationV2& op, uint32_t cluster_ops) {
|
|||
}
|
||||
|
||||
bool IsMetadataOp(const CowOperation& op) {
|
||||
switch (op.type) {
|
||||
switch (op.type()) {
|
||||
case kCowLabelOp:
|
||||
case kCowClusterOp:
|
||||
case kCowFooterOp:
|
||||
|
@ -138,7 +137,7 @@ bool IsMetadataOp(const CowOperation& op) {
|
|||
}
|
||||
|
||||
bool IsOrderedOp(const CowOperation& op) {
|
||||
switch (op.type) {
|
||||
switch (op.type()) {
|
||||
case kCowCopyOp:
|
||||
case kCowXorOp:
|
||||
return true;
|
||||
|
|
|
@ -345,7 +345,7 @@ bool CowReader::GetSequenceDataV2(std::vector<uint32_t>* merge_op_blocks,
|
|||
for (size_t i = 0; i < ops_->size(); i++) {
|
||||
auto& current_op = ops_->data()[i];
|
||||
|
||||
if (current_op.type == kCowSequenceOp) {
|
||||
if (current_op.type() == kCowSequenceOp) {
|
||||
size_t seq_len = current_op.data_length / sizeof(uint32_t);
|
||||
|
||||
merge_op_blocks->resize(merge_op_blocks->size() + seq_len);
|
||||
|
@ -637,11 +637,11 @@ std::unique_ptr<ICowOpIter> CowReader::GetMergeOpIter(bool ignore_progress) {
|
|||
}
|
||||
|
||||
bool CowReader::GetRawBytes(const CowOperation* op, void* buffer, size_t len, size_t* read) {
|
||||
switch (op->type) {
|
||||
switch (op->type()) {
|
||||
case kCowSequenceOp:
|
||||
case kCowReplaceOp:
|
||||
case kCowXorOp:
|
||||
return GetRawBytes(GetCowOpSourceInfoData(*op), buffer, len, read);
|
||||
return GetRawBytes(op->source(), buffer, len, read);
|
||||
default:
|
||||
LOG(ERROR) << "Cannot get raw bytes of non-data op: " << *op;
|
||||
return false;
|
||||
|
@ -730,10 +730,10 @@ ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_
|
|||
}
|
||||
|
||||
uint64_t offset;
|
||||
if (op->type == kCowXorOp) {
|
||||
if (op->type() == kCowXorOp) {
|
||||
offset = xor_data_loc_->at(op->new_block);
|
||||
} else {
|
||||
offset = GetCowOpSourceInfoData(*op);
|
||||
offset = op->source();
|
||||
}
|
||||
if (!decompressor ||
|
||||
((op->data_length == header_.block_size) && (header_.prefix.major_version == 3))) {
|
||||
|
@ -747,12 +747,12 @@ ssize_t CowReader::ReadData(const CowOperation* op, void* buffer, size_t buffer_
|
|||
}
|
||||
|
||||
bool CowReader::GetSourceOffset(const CowOperation* op, uint64_t* source_offset) {
|
||||
switch (op->type) {
|
||||
switch (op->type()) {
|
||||
case kCowCopyOp:
|
||||
*source_offset = GetCowOpSourceInfoData(*op) * header_.block_size;
|
||||
*source_offset = op->source() * header_.block_size;
|
||||
return true;
|
||||
case kCowXorOp:
|
||||
*source_offset = GetCowOpSourceInfoData(*op);
|
||||
*source_offset = op->source();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
|
|
@ -199,7 +199,7 @@ static bool Inspect(const std::string& path) {
|
|||
|
||||
if (!FLAGS_silent && FLAGS_show_ops) std::cout << *op << "\n";
|
||||
|
||||
if ((FLAGS_decompress || extract_to >= 0) && op->type == kCowReplaceOp) {
|
||||
if ((FLAGS_decompress || extract_to >= 0) && op->type() == kCowReplaceOp) {
|
||||
if (reader.ReadData(op, buffer.data(), buffer.size()) < 0) {
|
||||
std::cerr << "Failed to decompress for :" << *op << "\n";
|
||||
success = false;
|
||||
|
@ -213,12 +213,12 @@ static bool Inspect(const std::string& path) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
} else if (extract_to >= 0 && !IsMetadataOp(*op) && op->type != kCowZeroOp) {
|
||||
} else if (extract_to >= 0 && !IsMetadataOp(*op) && op->type() != kCowZeroOp) {
|
||||
PLOG(ERROR) << "Cannot extract op yet: " << *op;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (op->type == kCowSequenceOp && FLAGS_show_merge_sequence) {
|
||||
if (op->type() == kCowSequenceOp && FLAGS_show_merge_sequence) {
|
||||
size_t read;
|
||||
std::vector<uint32_t> merge_op_blocks;
|
||||
size_t seq_len = op->data_length / sizeof(uint32_t);
|
||||
|
@ -236,13 +236,13 @@ static bool Inspect(const std::string& path) {
|
|||
}
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
|
|
|
@ -205,7 +205,7 @@ bool CowParserV2::Translate(TranslatedCowOps* out) {
|
|||
const auto& v2_op = v2_ops_->at(i);
|
||||
|
||||
auto& new_op = out->ops->at(i);
|
||||
new_op.type = v2_op.type;
|
||||
new_op.set_type(v2_op.type);
|
||||
new_op.data_length = v2_op.data_length;
|
||||
|
||||
if (v2_op.new_block > std::numeric_limits<uint32_t>::max()) {
|
||||
|
@ -215,7 +215,7 @@ bool CowParserV2::Translate(TranslatedCowOps* out) {
|
|||
new_op.new_block = v2_op.new_block;
|
||||
|
||||
uint64_t source_info = v2_op.source;
|
||||
if (new_op.type != kCowLabelOp) {
|
||||
if (new_op.type() != kCowLabelOp) {
|
||||
source_info &= kCowOpSourceInfoDataMask;
|
||||
if (source_info != v2_op.source) {
|
||||
LOG(ERROR) << "Out-of-range source value in COW op: " << v2_op;
|
||||
|
@ -232,7 +232,7 @@ bool CowParserV2::Translate(TranslatedCowOps* out) {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
new_op.source_info = source_info;
|
||||
new_op.set_source(source_info);
|
||||
}
|
||||
|
||||
out->header = header_;
|
||||
|
|
|
@ -112,7 +112,7 @@ bool CowParserV3::ParseOps(borrowed_fd fd, const uint32_t op_index) {
|
|||
xor_data_loc_ = std::make_shared<std::unordered_map<uint64_t, uint64_t>>();
|
||||
|
||||
for (auto op : *ops_) {
|
||||
if (op.type == kCowXorOp) {
|
||||
if (op.type() == kCowXorOp) {
|
||||
xor_data_loc_->insert({op.new_block, data_pos});
|
||||
}
|
||||
data_pos += op.data_length;
|
||||
|
|
|
@ -147,7 +147,7 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
|
|||
op = ops_[chunk];
|
||||
}
|
||||
|
||||
if (!op || op->type == kCowCopyOp) {
|
||||
if (!op || op->type() == kCowCopyOp) {
|
||||
borrowed_fd fd = GetSourceFd();
|
||||
if (fd < 0) {
|
||||
// GetSourceFd sets errno.
|
||||
|
@ -169,15 +169,15 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
|
|||
// ReadFullyAtOffset sets errno.
|
||||
return -1;
|
||||
}
|
||||
} else if (op->type == kCowZeroOp) {
|
||||
} else if (op->type() == kCowZeroOp) {
|
||||
memset(buffer, 0, bytes_to_read);
|
||||
} else if (op->type == kCowReplaceOp) {
|
||||
} else if (op->type() == kCowReplaceOp) {
|
||||
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;
|
||||
}
|
||||
} else if (op->type == kCowXorOp) {
|
||||
} else if (op->type() == kCowXorOp) {
|
||||
borrowed_fd fd = GetSourceFd();
|
||||
if (fd < 0) {
|
||||
// GetSourceFd sets errno.
|
||||
|
@ -208,7 +208,7 @@ ssize_t CompressedSnapshotReader::ReadBlock(uint64_t chunk, size_t start_offset,
|
|||
((char*)buffer)[i] ^= data[i];
|
||||
}
|
||||
} else {
|
||||
LOG(ERROR) << "CompressedSnapshotReader unknown op type: " << uint32_t(op->type);
|
||||
LOG(ERROR) << "CompressedSnapshotReader unknown op type: " << uint32_t(op->type());
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -85,10 +85,10 @@ TEST_F(CowTest, CopyContiguous) {
|
|||
size_t i = 0;
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->type(), kCowCopyOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 10 + i);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 1000 + i);
|
||||
ASSERT_EQ(op->source(), 1000 + i);
|
||||
iter->Next();
|
||||
i += 1;
|
||||
}
|
||||
|
@ -131,10 +131,10 @@ TEST_F(CowTest, ReadWrite) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->type(), kCowCopyOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 10);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 20);
|
||||
ASSERT_EQ(op->source(), 20);
|
||||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
|
@ -142,7 +142,7 @@ TEST_F(CowTest, ReadWrite) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
|
@ -153,19 +153,19 @@ TEST_F(CowTest, ReadWrite) {
|
|||
op = iter->Get();
|
||||
|
||||
// Note: the zero operation gets split into two blocks.
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 51);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 52);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
|
@ -206,10 +206,10 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->type(), kCowCopyOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 10);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 20);
|
||||
ASSERT_EQ(op->source(), 20);
|
||||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
|
@ -217,10 +217,10 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowXorOp);
|
||||
ASSERT_EQ(op->type(), kCowXorOp);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 98314); // 4096 * 24 + 10
|
||||
ASSERT_EQ(op->source(), 98314); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
|
@ -229,19 +229,19 @@ TEST_F(CowTest, ReadWriteXor) {
|
|||
op = iter->Get();
|
||||
|
||||
// Note: the zero operation gets split into two blocks.
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 51);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 52);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
|
@ -273,7 +273,7 @@ TEST_F(CowTest, CompressGz) {
|
|||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->data_length, 56); // compressed!
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
|
@ -325,16 +325,16 @@ TEST_P(CompressionTest, ThreadedBatchWrites) {
|
|||
while (!iter->AtEnd()) {
|
||||
auto op = iter->Get();
|
||||
|
||||
if (op->type == kCowXorOp) {
|
||||
if (op->type() == kCowXorOp) {
|
||||
total_blocks += 1;
|
||||
std::string sink(xor_data.size(), '\0');
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 98314); // 4096 * 24 + 10
|
||||
ASSERT_EQ(op->source(), 98314); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, xor_data);
|
||||
}
|
||||
|
||||
if (op->type == kCowReplaceOp) {
|
||||
if (op->type() == kCowReplaceOp) {
|
||||
total_blocks += 1;
|
||||
if (op->new_block == 100) {
|
||||
data.resize(options.block_size);
|
||||
|
@ -399,7 +399,7 @@ TEST_P(CompressionTest, NoBatchWrites) {
|
|||
while (!iter->AtEnd()) {
|
||||
auto op = iter->Get();
|
||||
|
||||
if (op->type == kCowReplaceOp) {
|
||||
if (op->type() == kCowReplaceOp) {
|
||||
total_blocks += 1;
|
||||
if (op->new_block == 50) {
|
||||
data.resize(options.block_size);
|
||||
|
@ -519,7 +519,7 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->data_length, 56); // compressed!
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
|
@ -529,7 +529,7 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
ASSERT_EQ(op->type(), kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
|
@ -546,7 +546,7 @@ TEST_F(CowTest, ClusterCompressGz) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
ASSERT_EQ(op->type(), kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
|
@ -580,7 +580,7 @@ TEST_F(CowTest, CompressTwoBlocks) {
|
|||
std::string sink(options.block_size, '\0');
|
||||
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->new_block, 51);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
}
|
||||
|
@ -653,7 +653,7 @@ TEST_F(CowTest, AppendLabelSmall) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
|
||||
|
@ -663,14 +663,14 @@ TEST_F(CowTest, AppendLabelSmall) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 3);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 3);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
|
||||
|
@ -716,14 +716,14 @@ TEST_F(CowTest, AppendLabelMissing) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 0);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
|
@ -774,8 +774,8 @@ TEST_F(CowTest, AppendExtendedCorrupted) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 5);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 5);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_TRUE(iter->AtEnd());
|
||||
|
@ -825,7 +825,7 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data.substr(0, options.block_size));
|
||||
|
||||
|
@ -835,7 +835,7 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data.substr(options.block_size, 2 * options.block_size));
|
||||
|
||||
|
@ -843,26 +843,26 @@ TEST_F(CowTest, AppendbyLabel) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 4);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 4);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 5);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 5);
|
||||
|
||||
iter->Next();
|
||||
|
||||
|
@ -906,7 +906,7 @@ TEST_F(CowTest, ClusterTest) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data.substr(0, options.block_size));
|
||||
|
||||
|
@ -914,52 +914,52 @@ TEST_F(CowTest, ClusterTest) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 4);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 4);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
ASSERT_EQ(op->type(), kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 5);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 5);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->type(), kCowCopyOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
ASSERT_EQ(op->type(), kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 6);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 6);
|
||||
|
||||
iter->Next();
|
||||
|
||||
|
@ -1005,14 +1005,14 @@ TEST_F(CowTest, ClusterAppendTest) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowLabelOp);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 50);
|
||||
ASSERT_EQ(op->type(), kCowLabelOp);
|
||||
ASSERT_EQ(op->source(), 50);
|
||||
|
||||
iter->Next();
|
||||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data2);
|
||||
|
||||
|
@ -1020,7 +1020,7 @@ TEST_F(CowTest, ClusterAppendTest) {
|
|||
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowClusterOp);
|
||||
ASSERT_EQ(op->type(), kCowClusterOp);
|
||||
|
||||
iter->Next();
|
||||
|
||||
|
@ -1117,12 +1117,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_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++;
|
||||
}
|
||||
|
@ -1178,12 +1178,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_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++;
|
||||
}
|
||||
|
@ -1229,12 +1229,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_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++;
|
||||
}
|
||||
|
|
|
@ -128,19 +128,19 @@ TEST_F(CowTestV3, ZeroOp) {
|
|||
ASSERT_FALSE(iter->AtEnd());
|
||||
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 1);
|
||||
ASSERT_EQ(op->source_info, 0);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
|
||||
iter->Next();
|
||||
ASSERT_FALSE(iter->AtEnd());
|
||||
op = iter->Get();
|
||||
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 2);
|
||||
ASSERT_EQ(op->source_info, 0);
|
||||
ASSERT_EQ(op->source(), 0);
|
||||
}
|
||||
|
||||
TEST_F(CowTestV3, ReplaceOp) {
|
||||
|
@ -171,7 +171,7 @@ TEST_F(CowTestV3, ReplaceOp) {
|
|||
auto op = iter->Get();
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 5);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
|
@ -211,7 +211,7 @@ TEST_F(CowTestV3, ConsecutiveReplaceOp) {
|
|||
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->data_length, options.block_size);
|
||||
ASSERT_EQ(op->new_block, 5 + i);
|
||||
ASSERT_TRUE(
|
||||
|
@ -249,10 +249,10 @@ TEST_F(CowTestV3, CopyOp) {
|
|||
size_t i = 0;
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->type(), kCowCopyOp);
|
||||
ASSERT_EQ(op->data_length, 0);
|
||||
ASSERT_EQ(op->new_block, 10 + i);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 1000 + i);
|
||||
ASSERT_EQ(op->source(), 1000 + i);
|
||||
iter->Next();
|
||||
i += 1;
|
||||
}
|
||||
|
@ -285,10 +285,10 @@ TEST_F(CowTestV3, XorOp) {
|
|||
auto op = iter->Get();
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
ASSERT_EQ(op->type, kCowXorOp);
|
||||
ASSERT_EQ(op->type(), kCowXorOp);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 98314); // 4096 * 24 + 10
|
||||
ASSERT_EQ(op->source(), 98314); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
ASSERT_EQ(sink, data);
|
||||
}
|
||||
|
@ -325,10 +325,10 @@ TEST_F(CowTestV3, ConsecutiveXorOp) {
|
|||
|
||||
while (!iter->AtEnd()) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowXorOp);
|
||||
ASSERT_EQ(op->type(), kCowXorOp);
|
||||
ASSERT_EQ(op->data_length, 4096);
|
||||
ASSERT_EQ(op->new_block, 50 + i);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 98314 + (i * options.block_size)); // 4096 * 24 + 10
|
||||
ASSERT_EQ(op->source(), 98314 + (i * options.block_size)); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(
|
||||
ReadData(reader, op, sink.data() + (i * options.block_size), options.block_size));
|
||||
iter->Next();
|
||||
|
@ -378,7 +378,7 @@ TEST_F(CowTestV3, AllOpsWithCompression) {
|
|||
|
||||
while (i < 5) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowZeroOp);
|
||||
ASSERT_EQ(op->type(), kCowZeroOp);
|
||||
ASSERT_EQ(op->new_block, 10 + i);
|
||||
iter->Next();
|
||||
i++;
|
||||
|
@ -386,9 +386,9 @@ TEST_F(CowTestV3, AllOpsWithCompression) {
|
|||
i = 0;
|
||||
while (i < 5) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowCopyOp);
|
||||
ASSERT_EQ(op->type(), kCowCopyOp);
|
||||
ASSERT_EQ(op->new_block, 15 + i);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 3 + i);
|
||||
ASSERT_EQ(op->source(), 3 + i);
|
||||
iter->Next();
|
||||
i++;
|
||||
}
|
||||
|
@ -397,7 +397,7 @@ TEST_F(CowTestV3, AllOpsWithCompression) {
|
|||
|
||||
while (i < 5) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->new_block, 18 + i);
|
||||
ASSERT_TRUE(
|
||||
ReadData(reader, op, sink.data() + (i * options.block_size), options.block_size));
|
||||
|
@ -410,9 +410,9 @@ TEST_F(CowTestV3, AllOpsWithCompression) {
|
|||
std::fill(sink.begin(), sink.end(), '\0');
|
||||
while (i < 5) {
|
||||
auto op = iter->Get();
|
||||
ASSERT_EQ(op->type, kCowXorOp);
|
||||
ASSERT_EQ(op->type(), kCowXorOp);
|
||||
ASSERT_EQ(op->new_block, 50 + i);
|
||||
ASSERT_EQ(GetCowOpSourceInfoData(*op), 98314 + (i * options.block_size)); // 4096 * 24 + 10
|
||||
ASSERT_EQ(op->source(), 98314 + (i * options.block_size)); // 4096 * 24 + 10
|
||||
ASSERT_TRUE(
|
||||
ReadData(reader, op, sink.data() + (i * options.block_size), options.block_size));
|
||||
iter->Next();
|
||||
|
@ -448,7 +448,7 @@ TEST_F(CowTestV3, GzCompression) {
|
|||
|
||||
std::string sink(data.size(), '\0');
|
||||
|
||||
ASSERT_EQ(op->type, kCowReplaceOp);
|
||||
ASSERT_EQ(op->type(), kCowReplaceOp);
|
||||
ASSERT_EQ(op->data_length, 56); // compressed!
|
||||
ASSERT_EQ(op->new_block, 50);
|
||||
ASSERT_TRUE(ReadData(reader, op, sink.data(), sink.size()));
|
||||
|
|
|
@ -176,7 +176,7 @@ bool CowWriterV3::OpenForWrite() {
|
|||
}
|
||||
|
||||
bool CowWriterV3::OpenForAppend(uint64_t label) {
|
||||
CowHeaderV3 header_v3;
|
||||
CowHeaderV3 header_v3{};
|
||||
if (!ReadCowHeader(fd_, &header_v3)) {
|
||||
LOG(ERROR) << "Couldn't read Cow Header";
|
||||
return false;
|
||||
|
@ -208,10 +208,10 @@ bool CowWriterV3::OpenForAppend(uint64_t label) {
|
|||
|
||||
bool CowWriterV3::EmitCopy(uint64_t new_block, uint64_t old_block, uint64_t num_blocks) {
|
||||
for (size_t i = 0; i < num_blocks; i++) {
|
||||
CowOperationV3 op = {};
|
||||
op.type = kCowCopyOp;
|
||||
CowOperationV3 op{};
|
||||
op.set_type(kCowCopyOp);
|
||||
op.new_block = new_block + i;
|
||||
op.source_info = old_block + i;
|
||||
op.set_source(old_block + i);
|
||||
if (!WriteOperation(op)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -239,11 +239,11 @@ bool CowWriterV3::EmitBlocks(uint64_t new_block_start, const void* data, size_t
|
|||
CowOperation op = {};
|
||||
op.new_block = new_block_start + i;
|
||||
|
||||
op.type = type;
|
||||
op.set_type(type);
|
||||
if (type == kCowXorOp) {
|
||||
op.source_info = (old_block + i) * header_.block_size + offset;
|
||||
op.set_source((old_block + i) * header_.block_size + offset);
|
||||
} else {
|
||||
op.source_info = next_data_pos_;
|
||||
op.set_source(next_data_pos_);
|
||||
}
|
||||
std::basic_string<uint8_t> compressed_data;
|
||||
const void* out_data = iter;
|
||||
|
@ -273,11 +273,9 @@ bool CowWriterV3::EmitBlocks(uint64_t new_block_start, const void* data, size_t
|
|||
|
||||
bool CowWriterV3::EmitZeroBlocks(uint64_t new_block_start, uint64_t num_blocks) {
|
||||
for (uint64_t i = 0; i < num_blocks; i++) {
|
||||
CowOperationV3 op;
|
||||
op.type = kCowZeroOp;
|
||||
op.data_length = 0;
|
||||
CowOperationV3 op{};
|
||||
op.set_type(kCowZeroOp);
|
||||
op.new_block = new_block_start + i;
|
||||
op.source_info = 0;
|
||||
if (!WriteOperation(op)) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -406,9 +406,9 @@ bool Snapuserd::ReadMetadata() {
|
|||
break;
|
||||
}
|
||||
|
||||
if (cow_op->type == kCowReplaceOp) {
|
||||
if (cow_op->type() == kCowReplaceOp) {
|
||||
replace_ops++;
|
||||
} else if (cow_op->type == kCowZeroOp) {
|
||||
} else if (cow_op->type() == kCowZeroOp) {
|
||||
zero_ops++;
|
||||
}
|
||||
|
||||
|
@ -508,7 +508,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
// the merge of operations are done based on the ops present
|
||||
// in the file.
|
||||
//===========================================================
|
||||
uint64_t block_source = GetCowOpSourceInfoData(*cow_op);
|
||||
uint64_t block_source = cow_op->source();
|
||||
if (prev_id.has_value()) {
|
||||
if (dest_blocks.count(cow_op->new_block) || source_blocks.count(block_source)) {
|
||||
break;
|
||||
|
@ -540,7 +540,7 @@ bool Snapuserd::ReadMetadata() {
|
|||
chunk_vec_.push_back(std::make_pair(ChunkToSector(data_chunk_id), cow_op));
|
||||
offset += sizeof(struct disk_exception);
|
||||
num_ops += 1;
|
||||
if (cow_op->type == kCowCopyOp) {
|
||||
if (cow_op->type() == kCowCopyOp) {
|
||||
copy_ops++;
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ ReadAheadThread::ReadAheadThread(const std::string& cow_device, const std::strin
|
|||
}
|
||||
|
||||
void ReadAheadThread::CheckOverlap(const CowOperation* cow_op) {
|
||||
uint64_t source_block = GetCowOpSourceInfoData(*cow_op);
|
||||
uint64_t source_block = cow_op->source();
|
||||
if (dest_blocks_.count(cow_op->new_block) || source_blocks_.count(source_block)) {
|
||||
overlap_ = true;
|
||||
}
|
||||
|
@ -191,8 +191,8 @@ void ReadAheadThread::PrepareReadAhead(uint64_t* source_offset, int* pending_ops
|
|||
// Get the first block with offset
|
||||
const CowOperation* cow_op = GetRAOpIter();
|
||||
CHECK_NE(cow_op, nullptr);
|
||||
*source_offset = GetCowOpSourceInfoData(*cow_op);
|
||||
if (cow_op->type == kCowCopyOp) {
|
||||
*source_offset = cow_op->source();
|
||||
if (cow_op->type() == kCowCopyOp) {
|
||||
*source_offset *= BLOCK_SZ;
|
||||
}
|
||||
RAIterNext();
|
||||
|
@ -210,8 +210,8 @@ void ReadAheadThread::PrepareReadAhead(uint64_t* source_offset, int* pending_ops
|
|||
while (!RAIterDone() && num_ops) {
|
||||
const CowOperation* op = GetRAOpIter();
|
||||
CHECK_NE(op, nullptr);
|
||||
uint64_t next_offset = GetCowOpSourceInfoData(*op);
|
||||
if (op->type == kCowCopyOp) {
|
||||
uint64_t next_offset = op->source();
|
||||
if (op->type() == kCowCopyOp) {
|
||||
next_offset *= BLOCK_SZ;
|
||||
}
|
||||
if (next_offset + nr_consecutive * BLOCK_SZ != *source_offset) {
|
||||
|
|
|
@ -177,7 +177,7 @@ bool WorkerThread::ProcessCowOp(const CowOperation* cow_op) {
|
|||
return false;
|
||||
}
|
||||
|
||||
switch (cow_op->type) {
|
||||
switch (cow_op->type()) {
|
||||
case kCowReplaceOp: {
|
||||
return ProcessReplaceOp(cow_op);
|
||||
}
|
||||
|
@ -192,7 +192,7 @@ bool WorkerThread::ProcessCowOp(const CowOperation* cow_op) {
|
|||
|
||||
default: {
|
||||
SNAP_LOG(ERROR) << "Unsupported operation-type found: "
|
||||
<< static_cast<uint8_t>(cow_op->type);
|
||||
<< static_cast<uint8_t>(cow_op->type());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -114,13 +114,13 @@ bool MergeWorker::MergeReplaceZeroOps() {
|
|||
SNAP_LOG(ERROR) << "AcquireBuffer failed in MergeReplaceOps";
|
||||
return false;
|
||||
}
|
||||
if (cow_op->type == kCowReplaceOp) {
|
||||
if (cow_op->type() == kCowReplaceOp) {
|
||||
if (!reader_->ReadData(cow_op, buffer, BLOCK_SZ)) {
|
||||
SNAP_LOG(ERROR) << "Failed to read COW in merge";
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
CHECK(cow_op->type == kCowZeroOp);
|
||||
CHECK(cow_op->type() == kCowZeroOp);
|
||||
memset(buffer, 0, BLOCK_SZ);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ bool ReadWorker::ReadFromSourceDevice(const CowOperation* cow_op, void* buffer)
|
|||
<< " Op: " << *cow_op;
|
||||
if (!android::base::ReadFullyAtOffset(backing_store_fd_, buffer, BLOCK_SZ, offset)) {
|
||||
std::string op;
|
||||
if (cow_op->type == kCowCopyOp)
|
||||
if (cow_op->type() == kCowCopyOp)
|
||||
op = "Copy-op";
|
||||
else {
|
||||
op = "Xor-op";
|
||||
|
@ -133,7 +133,7 @@ bool ReadWorker::ProcessOrderedOp(const CowOperation* cow_op, void* buffer) {
|
|||
}
|
||||
case MERGE_GROUP_STATE::GROUP_MERGE_PENDING: {
|
||||
bool ret;
|
||||
if (cow_op->type == kCowCopyOp) {
|
||||
if (cow_op->type() == kCowCopyOp) {
|
||||
ret = ProcessCopyOp(cow_op, buffer);
|
||||
} else {
|
||||
ret = ProcessXorOp(cow_op, buffer);
|
||||
|
@ -167,7 +167,7 @@ bool ReadWorker::ProcessCowOp(const CowOperation* cow_op, void* buffer) {
|
|||
return false;
|
||||
}
|
||||
|
||||
switch (cow_op->type) {
|
||||
switch (cow_op->type()) {
|
||||
case kCowReplaceOp: {
|
||||
return ProcessReplaceOp(cow_op, buffer);
|
||||
}
|
||||
|
@ -184,7 +184,7 @@ bool ReadWorker::ProcessCowOp(const CowOperation* cow_op, void* buffer) {
|
|||
|
||||
default: {
|
||||
SNAP_LOG(ERROR) << "Unknown operation-type found: "
|
||||
<< static_cast<uint8_t>(cow_op->type);
|
||||
<< static_cast<uint8_t>(cow_op->type());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
|
|
@ -199,13 +199,13 @@ bool SnapshotHandler::ReadMetadata() {
|
|||
while (!cowop_iter->AtEnd()) {
|
||||
const CowOperation* cow_op = cowop_iter->Get();
|
||||
|
||||
if (cow_op->type == kCowCopyOp) {
|
||||
if (cow_op->type() == kCowCopyOp) {
|
||||
copy_ops += 1;
|
||||
} else if (cow_op->type == kCowReplaceOp) {
|
||||
} else if (cow_op->type() == kCowReplaceOp) {
|
||||
replace_ops += 1;
|
||||
} else if (cow_op->type == kCowZeroOp) {
|
||||
} else if (cow_op->type() == kCowZeroOp) {
|
||||
zero_ops += 1;
|
||||
} else if (cow_op->type == kCowXorOp) {
|
||||
} else if (cow_op->type() == kCowXorOp) {
|
||||
xor_ops += 1;
|
||||
}
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ int ReadAhead::PrepareNextReadAhead(uint64_t* source_offset, int* pending_ops,
|
|||
SNAP_LOG(ERROR) << "PrepareNextReadAhead operation has no source offset: " << *cow_op;
|
||||
return nr_consecutive;
|
||||
}
|
||||
if (cow_op->type == kCowXorOp) {
|
||||
if (cow_op->type() == kCowXorOp) {
|
||||
xor_op_vec.push_back(cow_op);
|
||||
}
|
||||
|
||||
|
@ -106,7 +106,7 @@ int ReadAhead::PrepareNextReadAhead(uint64_t* source_offset, int* pending_ops,
|
|||
break;
|
||||
}
|
||||
|
||||
if (op->type == kCowXorOp) {
|
||||
if (op->type() == kCowXorOp) {
|
||||
xor_op_vec.push_back(op);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue