89 řádky
2.6 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. #ifndef STORAGE_LEVELDB_DB_SNAPSHOT_H_
  5. #define STORAGE_LEVELDB_DB_SNAPSHOT_H_
  6. #include "db/dbformat.h"
  7. #include "leveldb/db.h"
  8. namespace leveldb {
  9. class SnapshotList;
  10. // Snapshots are kept in a doubly-linked list in the DB.
  11. // Each SnapshotImpl corresponds to a particular sequence number.
  12. class SnapshotImpl : public Snapshot {
  13. public:
  14. SnapshotImpl(SequenceNumber sequence_number)
  15. : sequence_number_(sequence_number) {}
  16. SequenceNumber sequence_number() const { return sequence_number_; }
  17. private:
  18. friend class SnapshotList;
  19. // SnapshotImpl is kept in a doubly-linked circular list. The SnapshotList
  20. // implementation operates on the next/previous fields direcly.
  21. SnapshotImpl* prev_;
  22. SnapshotImpl* next_;
  23. const SequenceNumber sequence_number_;
  24. #if !defined(NDEBUG)
  25. SnapshotList* list_ = nullptr;
  26. #endif // !defined(NDEBUG)
  27. };
  28. class SnapshotList {
  29. public:
  30. SnapshotList() : head_(0) {
  31. head_.prev_ = &head_;
  32. head_.next_ = &head_;
  33. }
  34. bool empty() const { return head_.next_ == &head_; }
  35. SnapshotImpl* oldest() const { assert(!empty()); return head_.next_; }
  36. SnapshotImpl* newest() const { assert(!empty()); return head_.prev_; }
  37. // Creates a SnapshotImpl and appends it to the end of the list.
  38. SnapshotImpl* New(SequenceNumber sequence_number) {
  39. assert(empty() || newest()->sequence_number_ <= sequence_number);
  40. SnapshotImpl* snapshot = new SnapshotImpl(sequence_number);
  41. #if !defined(NDEBUG)
  42. snapshot->list_ = this;
  43. #endif // !defined(NDEBUG)
  44. snapshot->next_ = &head_;
  45. snapshot->prev_ = head_.prev_;
  46. snapshot->prev_->next_ = snapshot;
  47. snapshot->next_->prev_ = snapshot;
  48. return snapshot;
  49. }
  50. // Removes a SnapshotImpl from this list.
  51. //
  52. // The snapshot must have been created by calling New() on this list.
  53. //
  54. // The snapshot pointer should not be const, because its memory is
  55. // deallocated. However, that would force us to change DB::ReleaseSnapshot(),
  56. // which is in the API, and currently takes a const Snapshot.
  57. void Delete(const SnapshotImpl* snapshot) {
  58. #if !defined(NDEBUG)
  59. assert(snapshot->list_ == this);
  60. #endif // !defined(NDEBUG)
  61. snapshot->prev_->next_ = snapshot->next_;
  62. snapshot->next_->prev_ = snapshot->prev_;
  63. delete snapshot;
  64. }
  65. private:
  66. // Dummy head of doubly-linked list of snapshots
  67. SnapshotImpl head_;
  68. };
  69. } // namespace leveldb
  70. #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_