snapuserd: Add XorSink
We can compute the xor while decompessing by computing it within a buffer. This would allow us to use a smaller buffer than the full block size if we wish to cut down on the extra memory required. Bug: 177104308 Test: cow_snapuserd_test (Snapuserd_Test.xor_buffer) Change-Id: Id18505841c77340760cea2d20e83454f1142b9b5
This commit is contained in:
parent
d091522de9
commit
edf7c667da
3 changed files with 76 additions and 0 deletions
|
|
@ -1039,6 +1039,35 @@ void CowSnapuserdMetadataTest::ValidateMetadata() {
|
|||
}
|
||||
}
|
||||
|
||||
TEST(Snapuserd_Test, xor_buffer) {
|
||||
std::string data = "Test String";
|
||||
std::string jumbled = {0x0C, 0x2A, 0x21, 0x54, 0x73, 0x27, 0x06, 0x1B, 0x07, 0x09, 0x46};
|
||||
std::string result = "XOR String!";
|
||||
|
||||
BufferSink sink;
|
||||
XorSink xor_sink;
|
||||
sink.Initialize(sizeof(struct dm_user_header) + 10);
|
||||
int buffsize = 5;
|
||||
xor_sink.Initialize(&sink, buffsize);
|
||||
|
||||
void* buff = sink.GetPayloadBuffer(data.length());
|
||||
memcpy(buff, data.data(), data.length());
|
||||
|
||||
size_t actual;
|
||||
size_t count = 0;
|
||||
while (count < data.length()) {
|
||||
void* xor_buff = xor_sink.GetBuffer(10, &actual);
|
||||
ASSERT_EQ(actual, buffsize);
|
||||
ASSERT_NE(xor_buff, nullptr);
|
||||
memcpy(xor_buff, jumbled.data() + count, buffsize);
|
||||
xor_sink.ReturnData(xor_buff, actual);
|
||||
count += actual;
|
||||
}
|
||||
|
||||
std::string answer = reinterpret_cast<char*>(sink.GetPayloadBufPtr());
|
||||
ASSERT_EQ(answer, result);
|
||||
}
|
||||
|
||||
TEST(Snapuserd_Test, Snapshot_Metadata) {
|
||||
CowSnapuserdMetadataTest harness;
|
||||
harness.Setup();
|
||||
|
|
|
|||
|
|
@ -107,6 +107,20 @@ class BufferSink : public IByteSink {
|
|||
size_t buffer_size_;
|
||||
};
|
||||
|
||||
class XorSink : public IByteSink {
|
||||
public:
|
||||
void Initialize(BufferSink* sink, size_t size);
|
||||
void Reset();
|
||||
void* GetBuffer(size_t requested, size_t* actual) override;
|
||||
bool ReturnData(void* buffer, size_t len) override;
|
||||
|
||||
private:
|
||||
BufferSink* bufsink_;
|
||||
std::unique_ptr<uint8_t[]> buffer_;
|
||||
size_t buffer_size_;
|
||||
size_t returned_;
|
||||
};
|
||||
|
||||
class Snapuserd;
|
||||
|
||||
class ReadAheadThread {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,39 @@ void* BufferSink::GetPayloadBufPtr() {
|
|||
return msg->payload.buf;
|
||||
}
|
||||
|
||||
void XorSink::Initialize(BufferSink* sink, size_t size) {
|
||||
bufsink_ = sink;
|
||||
buffer_size_ = size;
|
||||
returned_ = 0;
|
||||
buffer_ = std::make_unique<uint8_t[]>(size);
|
||||
}
|
||||
|
||||
void XorSink::Reset() {
|
||||
returned_ = 0;
|
||||
}
|
||||
|
||||
void* XorSink::GetBuffer(size_t requested, size_t* actual) {
|
||||
if (requested > buffer_size_) {
|
||||
*actual = buffer_size_;
|
||||
} else {
|
||||
*actual = requested;
|
||||
}
|
||||
return buffer_.get();
|
||||
}
|
||||
|
||||
bool XorSink::ReturnData(void* buffer, size_t len) {
|
||||
uint8_t* xor_data = reinterpret_cast<uint8_t*>(buffer);
|
||||
uint8_t* buff = reinterpret_cast<uint8_t*>(bufsink_->GetPayloadBuffer(len + returned_));
|
||||
if (buff == nullptr) {
|
||||
return false;
|
||||
}
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
buff[returned_ + i] ^= xor_data[i];
|
||||
}
|
||||
returned_ += len;
|
||||
return true;
|
||||
}
|
||||
|
||||
WorkerThread::WorkerThread(const std::string& cow_device, const std::string& backing_device,
|
||||
const std::string& control_device, const std::string& misc_name,
|
||||
std::shared_ptr<Snapuserd> snapuserd) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue