Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

320 righe
8.5 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_until_read_sampling_(RandomCompactionPeriod()) {
  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. // Picks the number of bytes that can be read until a compaction is scheduled.
  95. size_t RandomCompactionPeriod() {
  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. size_t bytes_until_read_sampling_;
  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. size_t bytes_read = k.size() + iter_->value().size();
  116. while (bytes_until_read_sampling_ < bytes_read) {
  117. bytes_until_read_sampling_ += RandomCompactionPeriod();
  118. db_->RecordReadSample(k);
  119. }
  120. assert(bytes_until_read_sampling_ >= bytes_read);
  121. bytes_until_read_sampling_ -= bytes_read;
  122. if (!ParseInternalKey(k, ikey)) {
  123. status_ = Status::Corruption("corrupted internal key in DBIter");
  124. return false;
  125. } else {
  126. return true;
  127. }
  128. }
  129. void DBIter::Next() {
  130. assert(valid_);
  131. if (direction_ == kReverse) { // Switch directions?
  132. direction_ = kForward;
  133. // iter_ is pointing just before the entries for this->key(),
  134. // so advance into the range of entries for this->key() and then
  135. // use the normal skipping code below.
  136. if (!iter_->Valid()) {
  137. iter_->SeekToFirst();
  138. } else {
  139. iter_->Next();
  140. }
  141. if (!iter_->Valid()) {
  142. valid_ = false;
  143. saved_key_.clear();
  144. return;
  145. }
  146. // saved_key_ already contains the key to skip past.
  147. } else {
  148. // Store in saved_key_ the current key so we skip it below.
  149. SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
  150. }
  151. FindNextUserEntry(true, &saved_key_);
  152. }
  153. void DBIter::FindNextUserEntry(bool skipping, std::string* skip) {
  154. // Loop until we hit an acceptable entry to yield
  155. assert(iter_->Valid());
  156. assert(direction_ == kForward);
  157. do {
  158. ParsedInternalKey ikey;
  159. if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
  160. switch (ikey.type) {
  161. case kTypeDeletion:
  162. // Arrange to skip all upcoming entries for this key since
  163. // they are hidden by this deletion.
  164. SaveKey(ikey.user_key, skip);
  165. skipping = true;
  166. break;
  167. case kTypeValue:
  168. if (skipping &&
  169. user_comparator_->Compare(ikey.user_key, *skip) <= 0) {
  170. // Entry hidden
  171. } else {
  172. valid_ = true;
  173. saved_key_.clear();
  174. return;
  175. }
  176. break;
  177. }
  178. }
  179. iter_->Next();
  180. } while (iter_->Valid());
  181. saved_key_.clear();
  182. valid_ = false;
  183. }
  184. void DBIter::Prev() {
  185. assert(valid_);
  186. if (direction_ == kForward) { // Switch directions?
  187. // iter_ is pointing at the current entry. Scan backwards until
  188. // the key changes so we can use the normal reverse scanning code.
  189. assert(iter_->Valid()); // Otherwise valid_ would have been false
  190. SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
  191. while (true) {
  192. iter_->Prev();
  193. if (!iter_->Valid()) {
  194. valid_ = false;
  195. saved_key_.clear();
  196. ClearSavedValue();
  197. return;
  198. }
  199. if (user_comparator_->Compare(ExtractUserKey(iter_->key()),
  200. saved_key_) < 0) {
  201. break;
  202. }
  203. }
  204. direction_ = kReverse;
  205. }
  206. FindPrevUserEntry();
  207. }
  208. void DBIter::FindPrevUserEntry() {
  209. assert(direction_ == kReverse);
  210. ValueType value_type = kTypeDeletion;
  211. if (iter_->Valid()) {
  212. do {
  213. ParsedInternalKey ikey;
  214. if (ParseKey(&ikey) && ikey.sequence <= sequence_) {
  215. if ((value_type != kTypeDeletion) &&
  216. user_comparator_->Compare(ikey.user_key, saved_key_) < 0) {
  217. // We encountered a non-deleted value in entries for previous keys,
  218. break;
  219. }
  220. value_type = ikey.type;
  221. if (value_type == kTypeDeletion) {
  222. saved_key_.clear();
  223. ClearSavedValue();
  224. } else {
  225. Slice raw_value = iter_->value();
  226. if (saved_value_.capacity() > raw_value.size() + 1048576) {
  227. std::string empty;
  228. swap(empty, saved_value_);
  229. }
  230. SaveKey(ExtractUserKey(iter_->key()), &saved_key_);
  231. saved_value_.assign(raw_value.data(), raw_value.size());
  232. }
  233. }
  234. iter_->Prev();
  235. } while (iter_->Valid());
  236. }
  237. if (value_type == kTypeDeletion) {
  238. // End
  239. valid_ = false;
  240. saved_key_.clear();
  241. ClearSavedValue();
  242. direction_ = kForward;
  243. } else {
  244. valid_ = true;
  245. }
  246. }
  247. void DBIter::Seek(const Slice& target) {
  248. direction_ = kForward;
  249. ClearSavedValue();
  250. saved_key_.clear();
  251. AppendInternalKey(
  252. &saved_key_, ParsedInternalKey(target, sequence_, kValueTypeForSeek));
  253. iter_->Seek(saved_key_);
  254. if (iter_->Valid()) {
  255. FindNextUserEntry(false, &saved_key_ /* temporary storage */);
  256. } else {
  257. valid_ = false;
  258. }
  259. }
  260. void DBIter::SeekToFirst() {
  261. direction_ = kForward;
  262. ClearSavedValue();
  263. iter_->SeekToFirst();
  264. if (iter_->Valid()) {
  265. FindNextUserEntry(false, &saved_key_ /* temporary storage */);
  266. } else {
  267. valid_ = false;
  268. }
  269. }
  270. void DBIter::SeekToLast() {
  271. direction_ = kReverse;
  272. ClearSavedValue();
  273. iter_->SeekToLast();
  274. FindPrevUserEntry();
  275. }
  276. } // anonymous namespace
  277. Iterator* NewDBIterator(
  278. DBImpl* db,
  279. const Comparator* user_key_comparator,
  280. Iterator* internal_iter,
  281. SequenceNumber sequence,
  282. uint32_t seed) {
  283. return new DBIter(db, user_key_comparator, internal_iter, sequence, seed);
  284. }
  285. } // namespace leveldb