| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197 |
- // Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- /**
- * The encoding of Cassandra Row Value.
- *
- * A Cassandra Row Value could either be a row tombstone,
- * or contains multiple columns, it has following fields:
- *
- * struct row_value {
- * int32_t local_deletion_time; // Time in second when the row is deleted,
- * // only used for Cassandra tombstone gc.
- * int64_t marked_for_delete_at; // Ms that marked this row is deleted.
- * struct column_base columns[]; // For non tombstone row, all columns
- * // are stored here.
- * }
- *
- * If the local_deletion_time and marked_for_delete_at is set, then this is
- * a tombstone, otherwise it contains multiple columns.
- *
- * There are three type of Columns: Normal Column, Expiring Column and Column
- * Tombstone, which have following fields:
- *
- * // Identify the type of the column.
- * enum mask {
- * DELETION_MASK = 0x01,
- * EXPIRATION_MASK = 0x02,
- * };
- *
- * struct column {
- * int8_t mask = 0;
- * int8_t index;
- * int64_t timestamp;
- * int32_t value_length;
- * char value[value_length];
- * }
- *
- * struct expiring_column {
- * int8_t mask = mask.EXPIRATION_MASK;
- * int8_t index;
- * int64_t timestamp;
- * int32_t value_length;
- * char value[value_length];
- * int32_t ttl;
- * }
- *
- * struct tombstone_column {
- * int8_t mask = mask.DELETION_MASK;
- * int8_t index;
- * int32_t local_deletion_time; // Similar to row_value's field.
- * int64_t marked_for_delete_at;
- * }
- */
- #pragma once
- #include <chrono>
- #include <memory>
- #include <vector>
- #include "rocksdb/merge_operator.h"
- #include "rocksdb/slice.h"
- #include "test_util/testharness.h"
- namespace ROCKSDB_NAMESPACE {
- namespace cassandra {
- // Identify the type of the column.
- enum ColumnTypeMask {
- DELETION_MASK = 0x01,
- EXPIRATION_MASK = 0x02,
- };
- class ColumnBase {
- public:
- ColumnBase(int8_t mask, int8_t index);
- virtual ~ColumnBase() = default;
- virtual int64_t Timestamp() const = 0;
- virtual int8_t Mask() const;
- virtual int8_t Index() const;
- virtual std::size_t Size() const;
- virtual void Serialize(std::string* dest) const;
- static std::shared_ptr<ColumnBase> Deserialize(const char* src,
- std::size_t offset);
- private:
- int8_t mask_;
- int8_t index_;
- };
- class Column : public ColumnBase {
- public:
- Column(int8_t mask, int8_t index, int64_t timestamp,
- int32_t value_size, const char* value);
- virtual int64_t Timestamp() const override;
- virtual std::size_t Size() const override;
- virtual void Serialize(std::string* dest) const override;
- static std::shared_ptr<Column> Deserialize(const char* src,
- std::size_t offset);
- private:
- int64_t timestamp_;
- int32_t value_size_;
- const char* value_;
- };
- class Tombstone : public ColumnBase {
- public:
- Tombstone(int8_t mask, int8_t index,
- int32_t local_deletion_time, int64_t marked_for_delete_at);
- virtual int64_t Timestamp() const override;
- virtual std::size_t Size() const override;
- virtual void Serialize(std::string* dest) const override;
- bool Collectable(int32_t gc_grace_period) const;
- static std::shared_ptr<Tombstone> Deserialize(const char* src,
- std::size_t offset);
- private:
- int32_t local_deletion_time_;
- int64_t marked_for_delete_at_;
- };
- class ExpiringColumn : public Column {
- public:
- ExpiringColumn(int8_t mask, int8_t index, int64_t timestamp,
- int32_t value_size, const char* value, int32_t ttl);
- virtual std::size_t Size() const override;
- virtual void Serialize(std::string* dest) const override;
- bool Expired() const;
- std::shared_ptr<Tombstone> ToTombstone() const;
- static std::shared_ptr<ExpiringColumn> Deserialize(const char* src,
- std::size_t offset);
- private:
- int32_t ttl_;
- std::chrono::time_point<std::chrono::system_clock> TimePoint() const;
- std::chrono::seconds Ttl() const;
- };
- typedef std::vector<std::shared_ptr<ColumnBase>> Columns;
- class RowValue {
- public:
- // Create a Row Tombstone.
- RowValue(int32_t local_deletion_time, int64_t marked_for_delete_at);
- // Create a Row containing columns.
- RowValue(Columns columns,
- int64_t last_modified_time);
- RowValue(const RowValue& /*that*/) = delete;
- RowValue(RowValue&& /*that*/) noexcept = default;
- RowValue& operator=(const RowValue& /*that*/) = delete;
- RowValue& operator=(RowValue&& /*that*/) = default;
- std::size_t Size() const;;
- bool IsTombstone() const;
- // For Tombstone this returns the marked_for_delete_at_,
- // otherwise it returns the max timestamp of containing columns.
- int64_t LastModifiedTime() const;
- void Serialize(std::string* dest) const;
- RowValue RemoveExpiredColumns(bool* changed) const;
- RowValue ConvertExpiredColumnsToTombstones(bool* changed) const;
- RowValue RemoveTombstones(int32_t gc_grace_period) const;
- bool Empty() const;
- static RowValue Deserialize(const char* src, std::size_t size);
- // Merge multiple rows according to their timestamp.
- static RowValue Merge(std::vector<RowValue>&& values);
- private:
- int32_t local_deletion_time_;
- int64_t marked_for_delete_at_;
- Columns columns_;
- int64_t last_modified_time_;
- FRIEND_TEST(RowValueTest, PurgeTtlShouldRemvoeAllColumnsExpired);
- FRIEND_TEST(RowValueTest, ExpireTtlShouldConvertExpiredColumnsToTombstones);
- FRIEND_TEST(RowValueMergeTest, Merge);
- FRIEND_TEST(RowValueMergeTest, MergeWithRowTombstone);
- FRIEND_TEST(CassandraFunctionalTest, SimpleMergeTest);
- FRIEND_TEST(
- CassandraFunctionalTest, CompactionShouldConvertExpiredColumnsToTombstone);
- FRIEND_TEST(
- CassandraFunctionalTest, CompactionShouldPurgeExpiredColumnsIfPurgeTtlIsOn);
- FRIEND_TEST(
- CassandraFunctionalTest, CompactionShouldRemoveRowWhenAllColumnExpiredIfPurgeTtlIsOn);
- FRIEND_TEST(CassandraFunctionalTest,
- CompactionShouldRemoveTombstoneExceedingGCGracePeriod);
- };
- } // namepsace cassandrda
- } // namespace ROCKSDB_NAMESPACE
|