小组成员:陈予曈,朱陈媛
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

172 lines
5.1 KiB

  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. //
  5. // WriteBatch::rep_ :=
  6. // sequence: fixed64
  7. // count: fixed32
  8. // data: record[count]
  9. // record :=
  10. // kTypeValue varstring varstring |
  11. // kTypeDeletion varstring
  12. // varstring :=
  13. // len: varint32
  14. // data: uint8[len]
  15. #include "leveldb/write_batch.h"
  16. #include "db/dbformat.h"
  17. #include "db/memtable.h"
  18. #include "db/write_batch_internal.h"
  19. #include "leveldb/db.h"
  20. #include "util/coding.h"
  21. // 添加所需头文件-橙
  22. #include <sstream>
  23. #include <iomanip>
  24. #include <ctime>
  25. #include <chrono>
  26. namespace leveldb {
  27. // WriteBatch header has an 8-byte sequence number followed by a 4-byte count.
  28. static const size_t kHeader = 12;
  29. WriteBatch::WriteBatch() { Clear(); }
  30. WriteBatch::~WriteBatch() = default;
  31. WriteBatch::Handler::~Handler() = default;
  32. void WriteBatch::Clear() {
  33. rep_.clear();
  34. rep_.resize(kHeader);
  35. }
  36. size_t WriteBatch::ApproximateSize() const { return rep_.size(); }
  37. Status WriteBatch::Iterate(Handler* handler) const {
  38. Slice input(rep_);
  39. if (input.size() < kHeader) {
  40. return Status::Corruption("malformed WriteBatch (too small)");
  41. }
  42. input.remove_prefix(kHeader);
  43. Slice key, value;
  44. int found = 0;
  45. while (!input.empty()) {
  46. found++;
  47. char tag = input[0];
  48. input.remove_prefix(1);
  49. switch (tag) {
  50. case kTypeValue:
  51. if (GetLengthPrefixedSlice(&input, &key) &&
  52. GetLengthPrefixedSlice(&input, &value)) {
  53. handler->Put(key, value);
  54. } else {
  55. return Status::Corruption("bad WriteBatch Put");
  56. }
  57. break;
  58. case kTypeDeletion:
  59. if (GetLengthPrefixedSlice(&input, &key)) {
  60. handler->Delete(key);
  61. } else {
  62. return Status::Corruption("bad WriteBatch Delete");
  63. }
  64. break;
  65. default:
  66. return Status::Corruption("unknown WriteBatch tag");
  67. }
  68. }
  69. if (found != WriteBatchInternal::Count(this)) {
  70. return Status::Corruption("WriteBatch has wrong count");
  71. } else {
  72. return Status::OK();
  73. }
  74. }
  75. int WriteBatchInternal::Count(const WriteBatch* b) {
  76. return DecodeFixed32(b->rep_.data() + 8);
  77. }
  78. void WriteBatchInternal::SetCount(WriteBatch* b, int n) {
  79. EncodeFixed32(&b->rep_[8], n);
  80. }
  81. SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
  82. return SequenceNumber(DecodeFixed64(b->rep_.data()));
  83. }
  84. void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {
  85. EncodeFixed64(&b->rep_[0], seq);
  86. }
  87. void WriteBatch::Put(const Slice& key, const Slice& value) {
  88. WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  89. rep_.push_back(static_cast<char>(kTypeValue));
  90. PutLengthPrefixedSlice(&rep_, key);
  91. PutLengthPrefixedSlice(&rep_, value);
  92. }
  93. // 添加ttl,新的put方法-橙
  94. void WriteBatch::Put(const Slice& key, const Slice& value, uint64_t ttl) {
  95. WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  96. rep_.push_back(static_cast<char>(kTypeValue));
  97. PutLengthPrefixedSlice(&rep_, key);
  98. // PutLengthPrefixedSlice(&rep_, value);
  99. // 获取当前时间,加上 TTL 得到过期时间戳
  100. auto expiration_time = std::chrono::system_clock::now()+ std::chrono::seconds(ttl);
  101. // 将过期时间戳转换为字符串
  102. std::time_t expiration_time_t = std::chrono::system_clock::to_time_t(expiration_time);
  103. std::stringstream ss;
  104. ss << std::put_time(std::localtime(&expiration_time_t), "%Y-%m-%d %H:%M:%S");
  105. std::string expiration_time_str = ss.str();
  106. // 将过期时间戳添加到值中
  107. std::string value_with_ttl(value.data(), value.size());
  108. value_with_ttl.append(expiration_time_str); // 拼接
  109. PutLengthPrefixedSlice(&rep_, Slice(value_with_ttl.data(), value_with_ttl.size()));
  110. }
  111. void WriteBatch::Delete(const Slice& key) {
  112. WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  113. rep_.push_back(static_cast<char>(kTypeDeletion));
  114. PutLengthPrefixedSlice(&rep_, key);
  115. }
  116. void WriteBatch::Append(const WriteBatch& source) {
  117. WriteBatchInternal::Append(this, &source);
  118. }
  119. namespace {
  120. class MemTableInserter : public WriteBatch::Handler {
  121. public:
  122. SequenceNumber sequence_;
  123. MemTable* mem_;
  124. void Put(const Slice& key, const Slice& value) override {
  125. mem_->Add(sequence_, kTypeValue, key, value);
  126. sequence_++;
  127. }
  128. void Delete(const Slice& key) override {
  129. mem_->Add(sequence_, kTypeDeletion, key, Slice());
  130. sequence_++;
  131. }
  132. };
  133. } // namespace
  134. Status WriteBatchInternal::InsertInto(const WriteBatch* b, MemTable* memtable) {
  135. MemTableInserter inserter;
  136. inserter.sequence_ = WriteBatchInternal::Sequence(b);
  137. inserter.mem_ = memtable;
  138. return b->Iterate(&inserter);
  139. }
  140. void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {
  141. assert(contents.size() >= kHeader);
  142. b->rep_.assign(contents.data(), contents.size());
  143. }
  144. void WriteBatchInternal::Append(WriteBatch* dst, const WriteBatch* src) {
  145. SetCount(dst, Count(dst) + Count(src));
  146. assert(src->rep_.size() >= kHeader);
  147. dst->rep_.append(src->rep_.data() + kHeader, src->rep_.size() - kHeader);
  148. }
  149. } // namespace leveldb