snapshot.h 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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 directly.
  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 {
  36. assert(!empty());
  37. return head_.next_;
  38. }
  39. SnapshotImpl* newest() const {
  40. assert(!empty());
  41. return head_.prev_;
  42. }
  43. // Creates a SnapshotImpl and appends it to the end of the list.
  44. SnapshotImpl* New(SequenceNumber sequence_number) {
  45. assert(empty() || newest()->sequence_number_ <= sequence_number);
  46. SnapshotImpl* snapshot = new SnapshotImpl(sequence_number);
  47. #if !defined(NDEBUG)
  48. snapshot->list_ = this;
  49. #endif // !defined(NDEBUG)
  50. snapshot->next_ = &head_;
  51. snapshot->prev_ = head_.prev_;
  52. snapshot->prev_->next_ = snapshot;
  53. snapshot->next_->prev_ = snapshot;
  54. return snapshot;
  55. }
  56. // Removes a SnapshotImpl from this list.
  57. //
  58. // The snapshot must have been created by calling New() on this list.
  59. //
  60. // The snapshot pointer should not be const, because its memory is
  61. // deallocated. However, that would force us to change DB::ReleaseSnapshot(),
  62. // which is in the API, and currently takes a const Snapshot.
  63. void Delete(const SnapshotImpl* snapshot) {
  64. #if !defined(NDEBUG)
  65. assert(snapshot->list_ == this);
  66. #endif // !defined(NDEBUG)
  67. snapshot->prev_->next_ = snapshot->next_;
  68. snapshot->next_->prev_ = snapshot->prev_;
  69. delete snapshot;
  70. }
  71. private:
  72. // Dummy head of doubly-linked list of snapshots
  73. SnapshotImpl head_;
  74. };
  75. } // namespace leveldb
  76. #endif // STORAGE_LEVELDB_DB_SNAPSHOT_H_