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