|
|
@ -14,26 +14,18 @@ |
|
|
|
namespace ROCKSDB_NAMESPACE { |
|
|
|
namespace ROCKSDB_NAMESPACE { |
|
|
|
namespace cassandra { |
|
|
|
namespace cassandra { |
|
|
|
namespace { |
|
|
|
namespace { |
|
|
|
const int32_t kDefaultLocalDeletionTime = |
|
|
|
const int32_t kDefaultLocalDeletionTime = std::numeric_limits<int32_t>::max(); |
|
|
|
std::numeric_limits<int32_t>::max(); |
|
|
|
const int64_t kDefaultMarkedForDeleteAt = std::numeric_limits<int64_t>::min(); |
|
|
|
const int64_t kDefaultMarkedForDeleteAt = |
|
|
|
} // namespace
|
|
|
|
std::numeric_limits<int64_t>::min(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ColumnBase::ColumnBase(int8_t mask, int8_t index) |
|
|
|
ColumnBase::ColumnBase(int8_t mask, int8_t index) |
|
|
|
: mask_(mask), index_(index) {} |
|
|
|
: mask_(mask), index_(index) {} |
|
|
|
|
|
|
|
|
|
|
|
std::size_t ColumnBase::Size() const { |
|
|
|
std::size_t ColumnBase::Size() const { return sizeof(mask_) + sizeof(index_); } |
|
|
|
return sizeof(mask_) + sizeof(index_); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int8_t ColumnBase::Mask() const { |
|
|
|
int8_t ColumnBase::Mask() const { return mask_; } |
|
|
|
return mask_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int8_t ColumnBase::Index() const { |
|
|
|
int8_t ColumnBase::Index() const { return index_; } |
|
|
|
return index_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void ColumnBase::Serialize(std::string* dest) const { |
|
|
|
void ColumnBase::Serialize(std::string* dest) const { |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int8_t>(mask_, dest); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int8_t>(mask_, dest); |
|
|
@ -52,22 +44,18 @@ std::shared_ptr<ColumnBase> ColumnBase::Deserialize(const char* src, |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Column::Column( |
|
|
|
Column::Column(int8_t mask, int8_t index, int64_t timestamp, int32_t value_size, |
|
|
|
int8_t mask, |
|
|
|
const char* value) |
|
|
|
int8_t index, |
|
|
|
: ColumnBase(mask, index), |
|
|
|
int64_t timestamp, |
|
|
|
timestamp_(timestamp), |
|
|
|
int32_t value_size, |
|
|
|
value_size_(value_size), |
|
|
|
const char* value |
|
|
|
value_(value) {} |
|
|
|
) : ColumnBase(mask, index), timestamp_(timestamp), |
|
|
|
|
|
|
|
value_size_(value_size), value_(value) {} |
|
|
|
int64_t Column::Timestamp() const { return timestamp_; } |
|
|
|
|
|
|
|
|
|
|
|
int64_t Column::Timestamp() const { |
|
|
|
|
|
|
|
return timestamp_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::size_t Column::Size() const { |
|
|
|
std::size_t Column::Size() const { |
|
|
|
return ColumnBase::Size() + sizeof(timestamp_) + sizeof(value_size_) |
|
|
|
return ColumnBase::Size() + sizeof(timestamp_) + sizeof(value_size_) + |
|
|
|
+ value_size_; |
|
|
|
value_size_; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Column::Serialize(std::string* dest) const { |
|
|
|
void Column::Serialize(std::string* dest) const { |
|
|
@ -77,7 +65,7 @@ void Column::Serialize(std::string* dest) const { |
|
|
|
dest->append(value_, value_size_); |
|
|
|
dest->append(value_, value_size_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Column> Column::Deserialize(const char *src, |
|
|
|
std::shared_ptr<Column> Column::Deserialize(const char* src, |
|
|
|
std::size_t offset) { |
|
|
|
std::size_t offset) { |
|
|
|
int8_t mask = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
int8_t mask = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
offset += sizeof(mask); |
|
|
|
offset += sizeof(mask); |
|
|
@ -89,19 +77,14 @@ std::shared_ptr<Column> Column::Deserialize(const char *src, |
|
|
|
int32_t value_size = |
|
|
|
int32_t value_size = |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Deserialize<int32_t>(src, offset); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Deserialize<int32_t>(src, offset); |
|
|
|
offset += sizeof(value_size); |
|
|
|
offset += sizeof(value_size); |
|
|
|
return std::make_shared<Column>( |
|
|
|
return std::make_shared<Column>(mask, index, timestamp, value_size, |
|
|
|
mask, index, timestamp, value_size, src + offset); |
|
|
|
src + offset); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
ExpiringColumn::ExpiringColumn( |
|
|
|
ExpiringColumn::ExpiringColumn(int8_t mask, int8_t index, int64_t timestamp, |
|
|
|
int8_t mask, |
|
|
|
int32_t value_size, const char* value, |
|
|
|
int8_t index, |
|
|
|
int32_t ttl) |
|
|
|
int64_t timestamp, |
|
|
|
: Column(mask, index, timestamp, value_size, value), ttl_(ttl) {} |
|
|
|
int32_t value_size, |
|
|
|
|
|
|
|
const char* value, |
|
|
|
|
|
|
|
int32_t ttl |
|
|
|
|
|
|
|
) : Column(mask, index, timestamp, value_size, value), |
|
|
|
|
|
|
|
ttl_(ttl) {} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::size_t ExpiringColumn::Size() const { |
|
|
|
std::size_t ExpiringColumn::Size() const { |
|
|
|
return Column::Size() + sizeof(ttl_); |
|
|
|
return Column::Size() + sizeof(ttl_); |
|
|
@ -112,8 +95,10 @@ void ExpiringColumn::Serialize(std::string* dest) const { |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int32_t>(ttl_, dest); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int32_t>(ttl_, dest); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::chrono::time_point<std::chrono::system_clock> ExpiringColumn::TimePoint() const { |
|
|
|
std::chrono::time_point<std::chrono::system_clock> ExpiringColumn::TimePoint() |
|
|
|
return std::chrono::time_point<std::chrono::system_clock>(std::chrono::microseconds(Timestamp())); |
|
|
|
const { |
|
|
|
|
|
|
|
return std::chrono::time_point<std::chrono::system_clock>( |
|
|
|
|
|
|
|
std::chrono::microseconds(Timestamp())); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::chrono::seconds ExpiringColumn::Ttl() const { |
|
|
|
std::chrono::seconds ExpiringColumn::Ttl() const { |
|
|
@ -131,15 +116,12 @@ std::shared_ptr<Tombstone> ExpiringColumn::ToTombstone() const { |
|
|
|
int64_t marked_for_delete_at = |
|
|
|
int64_t marked_for_delete_at = |
|
|
|
std::chrono::duration_cast<std::chrono::microseconds>(expired_at).count(); |
|
|
|
std::chrono::duration_cast<std::chrono::microseconds>(expired_at).count(); |
|
|
|
return std::make_shared<Tombstone>( |
|
|
|
return std::make_shared<Tombstone>( |
|
|
|
static_cast<int8_t>(ColumnTypeMask::DELETION_MASK), |
|
|
|
static_cast<int8_t>(ColumnTypeMask::DELETION_MASK), Index(), |
|
|
|
Index(), |
|
|
|
local_deletion_time, marked_for_delete_at); |
|
|
|
local_deletion_time, |
|
|
|
|
|
|
|
marked_for_delete_at); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<ExpiringColumn> ExpiringColumn::Deserialize( |
|
|
|
std::shared_ptr<ExpiringColumn> ExpiringColumn::Deserialize( |
|
|
|
const char *src, |
|
|
|
const char* src, std::size_t offset) { |
|
|
|
std::size_t offset) { |
|
|
|
|
|
|
|
int8_t mask = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
int8_t mask = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
offset += sizeof(mask); |
|
|
|
offset += sizeof(mask); |
|
|
|
int8_t index = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
int8_t index = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
@ -153,25 +135,21 @@ std::shared_ptr<ExpiringColumn> ExpiringColumn::Deserialize( |
|
|
|
const char* value = src + offset; |
|
|
|
const char* value = src + offset; |
|
|
|
offset += value_size; |
|
|
|
offset += value_size; |
|
|
|
int32_t ttl = ROCKSDB_NAMESPACE::cassandra::Deserialize<int32_t>(src, offset); |
|
|
|
int32_t ttl = ROCKSDB_NAMESPACE::cassandra::Deserialize<int32_t>(src, offset); |
|
|
|
return std::make_shared<ExpiringColumn>( |
|
|
|
return std::make_shared<ExpiringColumn>(mask, index, timestamp, value_size, |
|
|
|
mask, index, timestamp, value_size, value, ttl); |
|
|
|
value, ttl); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
Tombstone::Tombstone( |
|
|
|
Tombstone::Tombstone(int8_t mask, int8_t index, int32_t local_deletion_time, |
|
|
|
int8_t mask, |
|
|
|
int64_t marked_for_delete_at) |
|
|
|
int8_t index, |
|
|
|
: ColumnBase(mask, index), |
|
|
|
int32_t local_deletion_time, |
|
|
|
local_deletion_time_(local_deletion_time), |
|
|
|
int64_t marked_for_delete_at |
|
|
|
|
|
|
|
) : ColumnBase(mask, index), local_deletion_time_(local_deletion_time), |
|
|
|
|
|
|
|
marked_for_delete_at_(marked_for_delete_at) {} |
|
|
|
marked_for_delete_at_(marked_for_delete_at) {} |
|
|
|
|
|
|
|
|
|
|
|
int64_t Tombstone::Timestamp() const { |
|
|
|
int64_t Tombstone::Timestamp() const { return marked_for_delete_at_; } |
|
|
|
return marked_for_delete_at_; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
std::size_t Tombstone::Size() const { |
|
|
|
std::size_t Tombstone::Size() const { |
|
|
|
return ColumnBase::Size() + sizeof(local_deletion_time_) |
|
|
|
return ColumnBase::Size() + sizeof(local_deletion_time_) + |
|
|
|
+ sizeof(marked_for_delete_at_); |
|
|
|
sizeof(marked_for_delete_at_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void Tombstone::Serialize(std::string* dest) const { |
|
|
|
void Tombstone::Serialize(std::string* dest) const { |
|
|
@ -187,7 +165,7 @@ bool Tombstone::Collectable(int32_t gc_grace_period_in_seconds) const { |
|
|
|
return local_deleted_at + gc_grace_period < std::chrono::system_clock::now(); |
|
|
|
return local_deleted_at + gc_grace_period < std::chrono::system_clock::now(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
std::shared_ptr<Tombstone> Tombstone::Deserialize(const char *src, |
|
|
|
std::shared_ptr<Tombstone> Tombstone::Deserialize(const char* src, |
|
|
|
std::size_t offset) { |
|
|
|
std::size_t offset) { |
|
|
|
int8_t mask = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
int8_t mask = ROCKSDB_NAMESPACE::cassandra::Deserialize<int8_t>(src, offset); |
|
|
|
offset += sizeof(mask); |
|
|
|
offset += sizeof(mask); |
|
|
@ -198,26 +176,27 @@ std::shared_ptr<Tombstone> Tombstone::Deserialize(const char *src, |
|
|
|
offset += sizeof(int32_t); |
|
|
|
offset += sizeof(int32_t); |
|
|
|
int64_t marked_for_delete_at = |
|
|
|
int64_t marked_for_delete_at = |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Deserialize<int64_t>(src, offset); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Deserialize<int64_t>(src, offset); |
|
|
|
return std::make_shared<Tombstone>( |
|
|
|
return std::make_shared<Tombstone>(mask, index, local_deletion_time, |
|
|
|
mask, index, local_deletion_time, marked_for_delete_at); |
|
|
|
marked_for_delete_at); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
RowValue::RowValue(int32_t local_deletion_time, int64_t marked_for_delete_at) |
|
|
|
RowValue::RowValue(int32_t local_deletion_time, int64_t marked_for_delete_at) |
|
|
|
: local_deletion_time_(local_deletion_time), |
|
|
|
: local_deletion_time_(local_deletion_time), |
|
|
|
marked_for_delete_at_(marked_for_delete_at), columns_(), |
|
|
|
marked_for_delete_at_(marked_for_delete_at), |
|
|
|
|
|
|
|
columns_(), |
|
|
|
last_modified_time_(0) {} |
|
|
|
last_modified_time_(0) {} |
|
|
|
|
|
|
|
|
|
|
|
RowValue::RowValue(Columns columns, |
|
|
|
RowValue::RowValue(Columns columns, int64_t last_modified_time) |
|
|
|
int64_t last_modified_time) |
|
|
|
|
|
|
|
: local_deletion_time_(kDefaultLocalDeletionTime), |
|
|
|
: local_deletion_time_(kDefaultLocalDeletionTime), |
|
|
|
marked_for_delete_at_(kDefaultMarkedForDeleteAt), |
|
|
|
marked_for_delete_at_(kDefaultMarkedForDeleteAt), |
|
|
|
columns_(std::move(columns)), last_modified_time_(last_modified_time) {} |
|
|
|
columns_(std::move(columns)), |
|
|
|
|
|
|
|
last_modified_time_(last_modified_time) {} |
|
|
|
|
|
|
|
|
|
|
|
std::size_t RowValue::Size() const { |
|
|
|
std::size_t RowValue::Size() const { |
|
|
|
std::size_t size = sizeof(local_deletion_time_) |
|
|
|
std::size_t size = |
|
|
|
+ sizeof(marked_for_delete_at_); |
|
|
|
sizeof(local_deletion_time_) + sizeof(marked_for_delete_at_); |
|
|
|
for (const auto& column : columns_) { |
|
|
|
for (const auto& column : columns_) { |
|
|
|
size += column -> Size(); |
|
|
|
size += column->Size(); |
|
|
|
} |
|
|
|
} |
|
|
|
return size; |
|
|
|
return size; |
|
|
|
} |
|
|
|
} |
|
|
@ -238,7 +217,7 @@ void RowValue::Serialize(std::string* dest) const { |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int32_t>(local_deletion_time_, dest); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int32_t>(local_deletion_time_, dest); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int64_t>(marked_for_delete_at_, dest); |
|
|
|
ROCKSDB_NAMESPACE::cassandra::Serialize<int64_t>(marked_for_delete_at_, dest); |
|
|
|
for (const auto& column : columns_) { |
|
|
|
for (const auto& column : columns_) { |
|
|
|
column -> Serialize(dest); |
|
|
|
column->Serialize(dest); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -246,11 +225,11 @@ RowValue RowValue::RemoveExpiredColumns(bool* changed) const { |
|
|
|
*changed = false; |
|
|
|
*changed = false; |
|
|
|
Columns new_columns; |
|
|
|
Columns new_columns; |
|
|
|
for (auto& column : columns_) { |
|
|
|
for (auto& column : columns_) { |
|
|
|
if(column->Mask() == ColumnTypeMask::EXPIRATION_MASK) { |
|
|
|
if (column->Mask() == ColumnTypeMask::EXPIRATION_MASK) { |
|
|
|
std::shared_ptr<ExpiringColumn> expiring_column = |
|
|
|
std::shared_ptr<ExpiringColumn> expiring_column = |
|
|
|
std::static_pointer_cast<ExpiringColumn>(column); |
|
|
|
std::static_pointer_cast<ExpiringColumn>(column); |
|
|
|
|
|
|
|
|
|
|
|
if(expiring_column->Expired()){ |
|
|
|
if (expiring_column->Expired()) { |
|
|
|
*changed = true; |
|
|
|
*changed = true; |
|
|
|
continue; |
|
|
|
continue; |
|
|
|
} |
|
|
|
} |
|
|
@ -265,11 +244,11 @@ RowValue RowValue::ConvertExpiredColumnsToTombstones(bool* changed) const { |
|
|
|
*changed = false; |
|
|
|
*changed = false; |
|
|
|
Columns new_columns; |
|
|
|
Columns new_columns; |
|
|
|
for (auto& column : columns_) { |
|
|
|
for (auto& column : columns_) { |
|
|
|
if(column->Mask() == ColumnTypeMask::EXPIRATION_MASK) { |
|
|
|
if (column->Mask() == ColumnTypeMask::EXPIRATION_MASK) { |
|
|
|
std::shared_ptr<ExpiringColumn> expiring_column = |
|
|
|
std::shared_ptr<ExpiringColumn> expiring_column = |
|
|
|
std::static_pointer_cast<ExpiringColumn>(column); |
|
|
|
std::static_pointer_cast<ExpiringColumn>(column); |
|
|
|
|
|
|
|
|
|
|
|
if(expiring_column->Expired()) { |
|
|
|
if (expiring_column->Expired()) { |
|
|
|
std::shared_ptr<Tombstone> tombstone = expiring_column->ToTombstone(); |
|
|
|
std::shared_ptr<Tombstone> tombstone = expiring_column->ToTombstone(); |
|
|
|
new_columns.push_back(tombstone); |
|
|
|
new_columns.push_back(tombstone); |
|
|
|
*changed = true; |
|
|
|
*changed = true; |
|
|
@ -298,11 +277,9 @@ RowValue RowValue::RemoveTombstones(int32_t gc_grace_period) const { |
|
|
|
return RowValue(std::move(new_columns), last_modified_time_); |
|
|
|
return RowValue(std::move(new_columns), last_modified_time_); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
bool RowValue::Empty() const { |
|
|
|
bool RowValue::Empty() const { return columns_.empty(); } |
|
|
|
return columns_.empty(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
RowValue RowValue::Deserialize(const char *src, std::size_t size) { |
|
|
|
RowValue RowValue::Deserialize(const char* src, std::size_t size) { |
|
|
|
std::size_t offset = 0; |
|
|
|
std::size_t offset = 0; |
|
|
|
assert(size >= sizeof(local_deletion_time_) + sizeof(marked_for_delete_at_)); |
|
|
|
assert(size >= sizeof(local_deletion_time_) + sizeof(marked_for_delete_at_)); |
|
|
|
int32_t local_deletion_time = |
|
|
|
int32_t local_deletion_time = |
|
|
@ -321,9 +298,9 @@ RowValue RowValue::Deserialize(const char *src, std::size_t size) { |
|
|
|
int64_t last_modified_time = 0; |
|
|
|
int64_t last_modified_time = 0; |
|
|
|
while (offset < size) { |
|
|
|
while (offset < size) { |
|
|
|
auto c = ColumnBase::Deserialize(src, offset); |
|
|
|
auto c = ColumnBase::Deserialize(src, offset); |
|
|
|
offset += c -> Size(); |
|
|
|
offset += c->Size(); |
|
|
|
assert(offset <= size); |
|
|
|
assert(offset <= size); |
|
|
|
last_modified_time = std::max(last_modified_time, c -> Timestamp()); |
|
|
|
last_modified_time = std::max(last_modified_time, c->Timestamp()); |
|
|
|
columns.push_back(std::move(c)); |
|
|
|
columns.push_back(std::move(c)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -373,7 +350,7 @@ RowValue RowValue::Merge(std::vector<RowValue>&& values) { |
|
|
|
|
|
|
|
|
|
|
|
int64_t last_modified_time = 0; |
|
|
|
int64_t last_modified_time = 0; |
|
|
|
Columns columns; |
|
|
|
Columns columns; |
|
|
|
for (auto& pair: merged_columns) { |
|
|
|
for (auto& pair : merged_columns) { |
|
|
|
// For some row, its last_modified_time > row tombstone_timestamp, but
|
|
|
|
// For some row, its last_modified_time > row tombstone_timestamp, but
|
|
|
|
// it might have rows whose timestamp is ealier than tombstone, so we
|
|
|
|
// it might have rows whose timestamp is ealier than tombstone, so we
|
|
|
|
// ned to filter these rows.
|
|
|
|
// ned to filter these rows.
|
|
|
@ -386,5 +363,5 @@ RowValue RowValue::Merge(std::vector<RowValue>&& values) { |
|
|
|
return RowValue(std::move(columns), last_modified_time); |
|
|
|
return RowValue(std::move(columns), last_modified_time); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} // namepsace cassandrda
|
|
|
|
} // namespace cassandra
|
|
|
|
} // namespace ROCKSDB_NAMESPACE
|
|
|
|
} // namespace ROCKSDB_NAMESPACE
|
|
|
|