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