作者: 谢瑞阳 10225101483 徐翔宇 10225101535
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.

164 line
4.4 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. // kTypeLargeValueRef varstring varstring |
  12. // kTypeDeletion varstring
  13. // varstring :=
  14. // len: varint32
  15. // data: uint8[len]
  16. #include "include/write_batch.h"
  17. #include "include/db.h"
  18. #include "db/dbformat.h"
  19. #include "db/memtable.h"
  20. #include "db/write_batch_internal.h"
  21. #include "util/coding.h"
  22. namespace leveldb {
  23. WriteBatch::WriteBatch() {
  24. Clear();
  25. }
  26. WriteBatch::~WriteBatch() { }
  27. void WriteBatch::Clear() {
  28. rep_.clear();
  29. rep_.resize(12);
  30. }
  31. int WriteBatchInternal::Count(const WriteBatch* b) {
  32. return DecodeFixed32(b->rep_.data() + 8);
  33. }
  34. void WriteBatchInternal::SetCount(WriteBatch* b, int n) {
  35. EncodeFixed32(&b->rep_[8], n);
  36. }
  37. SequenceNumber WriteBatchInternal::Sequence(const WriteBatch* b) {
  38. return SequenceNumber(DecodeFixed64(b->rep_.data()));
  39. }
  40. void WriteBatchInternal::SetSequence(WriteBatch* b, SequenceNumber seq) {
  41. EncodeFixed64(&b->rep_[0], seq);
  42. }
  43. void WriteBatch::Put(const Slice& key, const Slice& value) {
  44. WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  45. rep_.push_back(static_cast<char>(kTypeValue));
  46. PutLengthPrefixedSlice(&rep_, key);
  47. PutLengthPrefixedSlice(&rep_, value);
  48. }
  49. void WriteBatchInternal::PutLargeValueRef(WriteBatch* b,
  50. const Slice& key,
  51. const LargeValueRef& large_ref) {
  52. WriteBatchInternal::SetCount(b, WriteBatchInternal::Count(b) + 1);
  53. b->rep_.push_back(static_cast<char>(kTypeLargeValueRef));
  54. PutLengthPrefixedSlice(&b->rep_, key);
  55. PutLengthPrefixedSlice(&b->rep_,
  56. Slice(large_ref.data, sizeof(large_ref.data)));
  57. }
  58. void WriteBatch::Delete(const Slice& key) {
  59. WriteBatchInternal::SetCount(this, WriteBatchInternal::Count(this) + 1);
  60. rep_.push_back(static_cast<char>(kTypeDeletion));
  61. PutLengthPrefixedSlice(&rep_, key);
  62. }
  63. Status WriteBatchInternal::InsertInto(const WriteBatch* b,
  64. MemTable* memtable) {
  65. const int count = WriteBatchInternal::Count(b);
  66. int found = 0;
  67. Iterator it(*b);
  68. for (; !it.Done(); it.Next()) {
  69. switch (it.op()) {
  70. case kTypeDeletion:
  71. memtable->Add(it.sequence_number(), kTypeDeletion, it.key(), Slice());
  72. break;
  73. case kTypeValue:
  74. memtable->Add(it.sequence_number(), kTypeValue, it.key(), it.value());
  75. break;
  76. case kTypeLargeValueRef:
  77. memtable->Add(it.sequence_number(), kTypeLargeValueRef,
  78. it.key(), it.value());
  79. break;
  80. }
  81. found++;
  82. }
  83. if (!it.status().ok()) {
  84. return it.status();
  85. } else if (found != count) {
  86. return Status::Corruption("wrong count in WriteBatch");
  87. }
  88. return Status::OK();
  89. }
  90. void WriteBatchInternal::SetContents(WriteBatch* b, const Slice& contents) {
  91. assert(contents.size() >= 12);
  92. b->rep_.assign(contents.data(), contents.size());
  93. }
  94. WriteBatchInternal::Iterator::Iterator(const WriteBatch& batch)
  95. : input_(WriteBatchInternal::Contents(&batch)),
  96. done_(false) {
  97. if (input_.size() < 12) {
  98. done_ = true;
  99. } else {
  100. seq_ = WriteBatchInternal::Sequence(&batch),
  101. input_.remove_prefix(12);
  102. GetNextEntry();
  103. }
  104. }
  105. void WriteBatchInternal::Iterator::Next() {
  106. assert(!done_);
  107. seq_++;
  108. GetNextEntry();
  109. }
  110. void WriteBatchInternal::Iterator::GetNextEntry() {
  111. if (input_.empty()) {
  112. done_ = true;
  113. return;
  114. }
  115. char tag = input_[0];
  116. input_.remove_prefix(1);
  117. switch (tag) {
  118. case kTypeValue:
  119. case kTypeLargeValueRef:
  120. if (GetLengthPrefixedSlice(&input_, &key_) &&
  121. GetLengthPrefixedSlice(&input_, &value_)) {
  122. op_ = static_cast<ValueType>(tag);
  123. } else {
  124. status_ = Status::Corruption("bad WriteBatch Put");
  125. done_ = true;
  126. input_.clear();
  127. }
  128. break;
  129. case kTypeDeletion:
  130. if (GetLengthPrefixedSlice(&input_, &key_)) {
  131. op_ = kTypeDeletion;
  132. } else {
  133. status_ = Status::Corruption("bad WriteBatch Delete");
  134. done_ = true;
  135. input_.clear();
  136. }
  137. break;
  138. default:
  139. status_ = Status::Corruption("unknown WriteBatch tag");
  140. done_ = true;
  141. input_.clear();
  142. break;
  143. }
  144. }
  145. }