Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

316 lignes
8.3 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. #include "db/db_iter.h"
  5. #include "db/filename.h"
  6. #include "db/db_impl.h"
  7. #include "db/dbformat.h"
  8. #include "leveldb/env.h"
  9. #include "leveldb/iterator.h"
  10. #include "port/port.h"
  11. #include "util/logging.h"
  12. #include "util/mutexlock.h"
  13. #include "util/random.h"
  14. namespace leveldb {
  15. #if 0
  16. static void DumpInternalIter(Iterator* iter) {
  17. for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
  18. ParsedInternalKey k;
  19. if (!ParseInternalKey(iter->key(), &k)) {
  20. fprintf(stderr, "Corrupt '%s'\n", EscapeString(iter->key()).c_str());
  21. } else {
  22. fprintf(stderr, "@ '%s'\n", k.DebugString().c_str());
  23. }
  24. }
  25. }
  26. #endif
  27. namespace {
  28. // Memtables and sstables that make the DB representation contain
  29. // (userkey,seq,type) => uservalue entries. DBIter
  30. // combines multiple entries for the same userkey found in the DB
  31. // representation into a single entry while accounting for sequence
  32. // numbers, deletion markers, overwrites, etc.
  33. class DBIter: public Iterator {
  34. public:
  35. // Which direction is the iterator currently moving?
  36. // (1) When moving forward, the internal iterator is positioned at
  37. // the exact entry that yields this->key(), this->value()
  38. // (2) When moving backwards, the internal iterator is positioned
  39. // just before all entries whose user key == this->key().
  40. enum Direction {
  41. kForward,
  42. kReverse
  43. };
  44. DBIter(DBImpl* db, const Comparator* cmp, Iterator* iter, SequenceNumber s,
  45. uint32_t seed)
  46. : db_(db),
  47. user_comparator_(cmp),
  48. iter_(iter),
  49. sequence_(s),
  50. direction_(kForward),
  51. valid_(false),
  52. rnd_(seed),
  53. bytes_counter_(RandomPeriod()) {
  54. }
  55. virtual ~DBIter() {
  56. delete iter_;
  57. }
  58. virtual bool Valid() const { return valid_; }
  59. virtual Slice key() const {
  60. assert(valid_);
  61. return (direction_ == kForward) ? ExtractUserKey(iter_->key()) : saved_key_;
  62. }
  63. virtual Slice value() const {
  64. assert(valid_);
  65. return (direction_ == kForward) ? iter_->value() : saved_value_;
  66. }
  67. virtual Status status() const {
  68. if (status_.ok()) {
  69. return iter_->status();
  70. } else {
  71. return status_;
  72. }
  73. }
  74. virtual void Next();
  75. virtual void Prev();
  76. virtual void Seek(const Slice& target);
  77. virtual void SeekToFirst();
  78. virtual void SeekToLast();
  79. private:
  80. void FindNextUserEntry(bool skipping, std::string* skip);
  81. void FindPrevUserEntry();
  82. bool ParseKey(ParsedInternalKey* key);
  83. inline void SaveKey(const Slice& k, std::string* dst) {
  84. dst->assign(k.data(), k.size());
  85. }
  86. inline void ClearSavedValue() {
  87. if (saved_value_.capacity() > 1048576) {
  88. std::string empty;
  89. swap(empty, saved_value_);
  90. } else {
  91. saved_value_.clear();
  92. }
  93. }
  94. // Pick next gap with average value of config::kReadBytesPeriod.
  95. ssize_t RandomPeriod() {
  96. return rnd_.Uniform(2*config::kReadBytesPeriod);
  97. }
  98. DBImpl* db_;
  99. const Comparator* const user_comparator_;
  100. Iterator* const iter_;
  101. SequenceNumber const sequence_;
  102. Status status_;
  103. std::string saved_key_; // == current key when direction_==kReverse
  104. std::string saved_value_; // == current raw value when direction_==kReverse
  105. Direction direction_;
  106. bool valid_;
  107. Random rnd_;
  108. ssize_t bytes_counter_;
  109. // No copying allowed
  110. DBIter(const DBIter&);
  111. void operator=(const DBIter&);
  112. };
  113. inline bool DBIter::ParseKey(ParsedInternalKey* ikey) {
  114. Slice k = iter_->key();
  115. ssize_t n = k.size() + iter_->value().size();
  116. bytes_counter_ -= n;
  117. while (bytes_counter_ < 0) {
  118. bytes_counter_ += RandomPeriod();
  119. db_->RecordReadSample(k);
  120. }
  121. if (!ParseInternalKey(k, ikey)) {
  122. status_ = Status::Corruption("corrupted internal key in DBIter");
  123. return false;
  124. } else {
  125. return true;
  126. }
  127. }
  128. void DBIter::Next() {
  129. assert(valid_);
  130. if (direction_ == kReverse) { // Switch directions?
  131. direction_ = kForward;
  132. // iter_ is pointing just before the entries for this->key(),
  133. // so advance into the range of entries for this->key() and then
  134. // use the normal skipping code below.
  135. if (!iter_->Valid()) {
  136. iter_->SeekToFirst();
  137. } else {
  138. iter_->Next();
  139. }
  140. if (!iter_->Valid()) {
  141. valid_ = false;
  142. saved_key_.clear();
  143. return;
  144. }
  145. }
  146. // Temporarily use saved_key_ as storage for key to skip.
  147. std::string* skip = &saved_key_;
  148. SaveKey(ExtractUserKey(iter_->key()), skip);
  149. FindNextUserEntry(true, skip);
  150. }
  151. void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
  152. // Loop until we hit an acceptable entry to yield
  153. assert(iter_->Valid());
  154. assert(direction_ == kForward);
  155. do {
  156. ParsedInternalKey ikey;
  157. if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
  158. switch (ikey.type) {
  159. case kTypeDeletion:
  160. // Arrange to skip all upcoming entries for this key since
  161. // they are hidden by this deletion.
  162. SaveKey(ikey.user_key, skip);
  163. skipping = true;
  164. break;
  165. case kTypeValue:
  166. if (skipping &&
  167. user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
  168. // Entry hidden
  169. } else {
  170. valid_ = true;
  171. saved_key_.clear();
  172. return;
  173. }
  174. break;
  175. }
  176. }
  177. iter_->Next();
  178. } while (iter_->Valid());
  179. saved_key_.clear();
  180. valid_ = false;
  181. }
  182. void DBIter::Prev() {
  183. assert(valid_);
  184. if (direction_ == kForward) { // Switch directions?
  185. // iter_ is pointing at the current entry. Scan backwards until
  186. // the key changes so we can use the normal reverse scanning code.
  187. assert(iter_->Valid()); // Otherwise valid_ would have been false
  188. SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
  189. while (true) {
  190. iter_->Prev();
  191. if (!iter_->Valid()) {
  192. valid_ = false;
  193. saved_key_.clear();
  194. ClearSavedValue();
  195. return;
  196. }
  197. if (user_comparator_->Compare(ExtractUserKey(iter_->key()),
  198. saved_key_) < 0) {
  199. break;
  200. }
  201. }
  202. direction_ = kReverse;
  203. }
  204. FindPrevUserEntry();
  205. }
  206. void DBIter::FindPrevUserEntry() {
  207. assert(direction_ == kReverse);
  208. ValueType value_type = kTypeDeletion;
  209. if (iter_->Valid()) {
  210. do {
  211. ParsedInternalKey ikey;
  212. if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
  213. if ((value_type != kTypeDeletion) &&
  214. user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {
  215. // We encountered a non-deleted value in entries for previous keys,
  216. break;
  217. }
  218. value_type = ikey.type;
  219. if (value_type == kTypeDeletion) {
  220. saved_key_.clear();
  221. ClearSavedValue();
  222. } else {
  223. Slice raw_value = iter_->value();
  224. if (saved_value_.capacity() > raw_value.size() + 1048576) {
  225. std::string empty;
  226. swap(empty, saved_value_);
  227. }
  228. SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
  229. saved_value_.assign(raw_value.data(), raw_value.size());
  230. }
  231. }
  232. iter_->Prev();
  233. } while (iter_->Valid());
  234. }
  235. if (value_type == kTypeDeletion) {
  236. // End
  237. valid_ = false;
  238. saved_key_.clear();
  239. ClearSavedValue();
  240. direction_ = kForward;
  241. } else {
  242. valid_ = true;
  243. }
  244. }
  245. void DBIter::Seek(const Slice& target) {
  246. direction_ = kForward;
  247. ClearSavedValue();
  248. saved_key_.clear();
  249. AppendInternalKey(
  250. &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));
  251. iter_->Seek(saved_key_);
  252. if (iter_->Valid()) {
  253. FindNextUserEntry(false, &saved_key_ /* temporary storage */);
  254. } else {
  255. valid_ = false;
  256. }
  257. }
  258. void DBIter::SeekToFirst() {
  259. direction_ = kForward;
  260. ClearSavedValue();
  261. iter_->SeekToFirst();
  262. if (iter_->Valid()) {
  263. FindNextUserEntry(false, &saved_key_ /* temporary storage */);
  264. } else {
  265. valid_ = false;
  266. }
  267. }
  268. void DBIter::SeekToLast() {
  269. direction_ = kReverse;
  270. ClearSavedValue();
  271. iter_->SeekToLast();
  272. FindPrevUserEntry();
  273. }
  274. } // anonymous namespace
  275. Iterator* NewDBIterator(
  276. DBImpl* db,
  277. const Comparator* user_key_comparator,
  278. Iterator* internal_iter,
  279. SequenceNumber sequence,
  280. uint32_t seed) {
  281. return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
  282. }
  283. } // namespace leveldb