format.h 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. // Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. /**
  6. * The encoding of Cassandra Row Value.
  7. *
  8. * A Cassandra Row Value could either be a row tombstone,
  9. * or contains multiple columns, it has following fields:
  10. *
  11. * struct row_value {
  12. * int32_t local_deletion_time; // Time in second when the row is deleted,
  13. * // only used for Cassandra tombstone gc.
  14. * int64_t marked_for_delete_at; // Ms that marked this row is deleted.
  15. * struct column_base columns[]; // For non tombstone row, all columns
  16. * // are stored here.
  17. * }
  18. *
  19. * If the local_deletion_time and marked_for_delete_at is set, then this is
  20. * a tombstone, otherwise it contains multiple columns.
  21. *
  22. * There are three type of Columns: Normal Column, Expiring Column and Column
  23. * Tombstone, which have following fields:
  24. *
  25. * // Identify the type of the column.
  26. * enum mask {
  27. * DELETION_MASK = 0x01,
  28. * EXPIRATION_MASK = 0x02,
  29. * };
  30. *
  31. * struct column {
  32. * int8_t mask = 0;
  33. * int8_t index;
  34. * int64_t timestamp;
  35. * int32_t value_length;
  36. * char value[value_length];
  37. * }
  38. *
  39. * struct expiring_column {
  40. * int8_t mask = mask.EXPIRATION_MASK;
  41. * int8_t index;
  42. * int64_t timestamp;
  43. * int32_t value_length;
  44. * char value[value_length];
  45. * int32_t ttl;
  46. * }
  47. *
  48. * struct tombstone_column {
  49. * int8_t mask = mask.DELETION_MASK;
  50. * int8_t index;
  51. * int32_t local_deletion_time; // Similar to row_value's field.
  52. * int64_t marked_for_delete_at;
  53. * }
  54. */
  55. #pragma once
  56. #include <chrono>
  57. #include <memory>
  58. #include <vector>
  59. #include "rocksdb/merge_operator.h"
  60. #include "rocksdb/slice.h"
  61. #include "test_util/testharness.h"
  62. namespace ROCKSDB_NAMESPACE {
  63. namespace cassandra {
  64. // Identify the type of the column.
  65. enum ColumnTypeMask {
  66. DELETION_MASK = 0x01,
  67. EXPIRATION_MASK = 0x02,
  68. };
  69. class ColumnBase {
  70. public:
  71. ColumnBase(int8_t mask, int8_t index);
  72. virtual ~ColumnBase() = default;
  73. virtual int64_t Timestamp() const = 0;
  74. virtual int8_t Mask() const;
  75. virtual int8_t Index() const;
  76. virtual std::size_t Size() const;
  77. virtual void Serialize(std::string* dest) const;
  78. static std::shared_ptr<ColumnBase> Deserialize(const char* src,
  79. std::size_t offset);
  80. private:
  81. int8_t mask_;
  82. int8_t index_;
  83. };
  84. class Column : public ColumnBase {
  85. public:
  86. Column(int8_t mask, int8_t index, int64_t timestamp,
  87. int32_t value_size, const char* value);
  88. virtual int64_t Timestamp() const override;
  89. virtual std::size_t Size() const override;
  90. virtual void Serialize(std::string* dest) const override;
  91. static std::shared_ptr<Column> Deserialize(const char* src,
  92. std::size_t offset);
  93. private:
  94. int64_t timestamp_;
  95. int32_t value_size_;
  96. const char* value_;
  97. };
  98. class Tombstone : public ColumnBase {
  99. public:
  100. Tombstone(int8_t mask, int8_t index,
  101. int32_t local_deletion_time, int64_t marked_for_delete_at);
  102. virtual int64_t Timestamp() const override;
  103. virtual std::size_t Size() const override;
  104. virtual void Serialize(std::string* dest) const override;
  105. bool Collectable(int32_t gc_grace_period) const;
  106. static std::shared_ptr<Tombstone> Deserialize(const char* src,
  107. std::size_t offset);
  108. private:
  109. int32_t local_deletion_time_;
  110. int64_t marked_for_delete_at_;
  111. };
  112. class ExpiringColumn : public Column {
  113. public:
  114. ExpiringColumn(int8_t mask, int8_t index, int64_t timestamp,
  115. int32_t value_size, const char* value, int32_t ttl);
  116. virtual std::size_t Size() const override;
  117. virtual void Serialize(std::string* dest) const override;
  118. bool Expired() const;
  119. std::shared_ptr<Tombstone> ToTombstone() const;
  120. static std::shared_ptr<ExpiringColumn> Deserialize(const char* src,
  121. std::size_t offset);
  122. private:
  123. int32_t ttl_;
  124. std::chrono::time_point<std::chrono::system_clock> TimePoint() const;
  125. std::chrono::seconds Ttl() const;
  126. };
  127. typedef std::vector<std::shared_ptr<ColumnBase>> Columns;
  128. class RowValue {
  129. public:
  130. // Create a Row Tombstone.
  131. RowValue(int32_t local_deletion_time, int64_t marked_for_delete_at);
  132. // Create a Row containing columns.
  133. RowValue(Columns columns,
  134. int64_t last_modified_time);
  135. RowValue(const RowValue& /*that*/) = delete;
  136. RowValue(RowValue&& /*that*/) noexcept = default;
  137. RowValue& operator=(const RowValue& /*that*/) = delete;
  138. RowValue& operator=(RowValue&& /*that*/) = default;
  139. std::size_t Size() const;;
  140. bool IsTombstone() const;
  141. // For Tombstone this returns the marked_for_delete_at_,
  142. // otherwise it returns the max timestamp of containing columns.
  143. int64_t LastModifiedTime() const;
  144. void Serialize(std::string* dest) const;
  145. RowValue RemoveExpiredColumns(bool* changed) const;
  146. RowValue ConvertExpiredColumnsToTombstones(bool* changed) const;
  147. RowValue RemoveTombstones(int32_t gc_grace_period) const;
  148. bool Empty() const;
  149. static RowValue Deserialize(const char* src, std::size_t size);
  150. // Merge multiple rows according to their timestamp.
  151. static RowValue Merge(std::vector<RowValue>&& values);
  152. private:
  153. int32_t local_deletion_time_;
  154. int64_t marked_for_delete_at_;
  155. Columns columns_;
  156. int64_t last_modified_time_;
  157. FRIEND_TEST(RowValueTest, PurgeTtlShouldRemvoeAllColumnsExpired);
  158. FRIEND_TEST(RowValueTest, ExpireTtlShouldConvertExpiredColumnsToTombstones);
  159. FRIEND_TEST(RowValueMergeTest, Merge);
  160. FRIEND_TEST(RowValueMergeTest, MergeWithRowTombstone);
  161. FRIEND_TEST(CassandraFunctionalTest, SimpleMergeTest);
  162. FRIEND_TEST(
  163. CassandraFunctionalTest, CompactionShouldConvertExpiredColumnsToTombstone);
  164. FRIEND_TEST(
  165. CassandraFunctionalTest, CompactionShouldPurgeExpiredColumnsIfPurgeTtlIsOn);
  166. FRIEND_TEST(
  167. CassandraFunctionalTest, CompactionShouldRemoveRowWhenAllColumnExpiredIfPurgeTtlIsOn);
  168. FRIEND_TEST(CassandraFunctionalTest,
  169. CompactionShouldRemoveTombstoneExceedingGCGracePeriod);
  170. };
  171. } // namepsace cassandrda
  172. } // namespace ROCKSDB_NAMESPACE