Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ac029e50 authored by Daniel Rosenberg's avatar Daniel Rosenberg Committed by Automerger Merge Worker
Browse files

Merge "libsnapshot: Add cluster breaks after ops" am: 53296d80 am: 588f732b

Original change: https://android-review.googlesource.com/c/platform/system/core/+/1533826

MUST ONLY BE SUBMITTED BY AUTOMERGER

Change-Id: Ie9c8177ba2c402efb0b77fdc05f775aab3b673ac
parents f020607b 588f732b
Loading
Loading
Loading
Loading
+64 −0
Original line number Diff line number Diff line
@@ -171,6 +171,70 @@ TEST_F(CowTest, CompressGz) {
    ASSERT_TRUE(iter->Done());
}

TEST_F(CowTest, ClusterCompressGz) {
    CowOptions options;
    options.compression = "gz";
    options.cluster_ops = 2;
    CowWriter writer(options);

    ASSERT_TRUE(writer.Initialize(cow_->fd));

    std::string data = "This is some data, believe it";
    data.resize(options.block_size, '\0');
    ASSERT_TRUE(writer.AddRawBlocks(50, data.data(), data.size()));

    std::string data2 = "More data!";
    data2.resize(options.block_size, '\0');
    ASSERT_TRUE(writer.AddRawBlocks(51, data2.data(), data2.size()));

    ASSERT_TRUE(writer.Finalize());

    ASSERT_EQ(lseek(cow_->fd, 0, SEEK_SET), 0);

    CowReader reader;
    ASSERT_TRUE(reader.Parse(cow_->fd));

    auto iter = reader.GetOpIter();
    ASSERT_NE(iter, nullptr);
    ASSERT_FALSE(iter->Done());
    auto op = &iter->Get();

    StringSink sink;

    ASSERT_EQ(op->type, kCowReplaceOp);
    ASSERT_EQ(op->compression, kCowCompressGz);
    ASSERT_EQ(op->data_length, 56);  // compressed!
    ASSERT_EQ(op->new_block, 50);
    ASSERT_TRUE(reader.ReadData(*op, &sink));
    ASSERT_EQ(sink.stream(), data);

    iter->Next();
    ASSERT_FALSE(iter->Done());
    op = &iter->Get();

    ASSERT_EQ(op->type, kCowClusterOp);

    iter->Next();
    ASSERT_FALSE(iter->Done());
    op = &iter->Get();

    sink.Reset();
    ASSERT_EQ(op->compression, kCowCompressGz);
    ASSERT_EQ(op->data_length, 41);  // compressed!
    ASSERT_EQ(op->new_block, 51);
    ASSERT_TRUE(reader.ReadData(*op, &sink));
    ASSERT_EQ(sink.stream(), data2);

    iter->Next();
    ASSERT_FALSE(iter->Done());
    op = &iter->Get();

    ASSERT_EQ(op->type, kCowClusterOp);

    iter->Next();
    ASSERT_TRUE(iter->Done());
}

TEST_F(CowTest, CompressTwoBlocks) {
    CowOptions options;
    options.compression = "gz";
+5 −5
Original line number Diff line number Diff line
@@ -433,11 +433,6 @@ bool CowWriter::GetDataPos(uint64_t* pos) {
}

bool CowWriter::WriteOperation(const CowOperation& op, const void* data, size_t size) {
    // If there isn't room for this op and the cluster end op, end the current cluster
    if (cluster_size_ && op.type != kCowClusterOp &&
        cluster_size_ < current_cluster_size_ + 2 * sizeof(op)) {
        if (!EmitCluster()) return false;
    }
    if (lseek(fd_.get(), next_op_pos_, SEEK_SET) < 0) {
        PLOG(ERROR) << "lseek failed for writing operation.";
        return false;
@@ -449,6 +444,11 @@ bool CowWriter::WriteOperation(const CowOperation& op, const void* data, size_t
        if (!WriteRawData(data, size)) return false;
    }
    AddOperation(op);
    // If there isn't room for another op and the cluster end op, end the current cluster
    if (cluster_size_ && op.type != kCowClusterOp &&
        cluster_size_ < current_cluster_size_ + 2 * sizeof(op)) {
        if (!EmitCluster()) return false;
    }
    return true;
}