snapshot.h raw

   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        : sequence_number_(sequence_number) {}
  21  
  22    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 directly.
  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    SnapshotList() : head_(0) {
  42      head_.prev_ = &head_;
  43      head_.next_ = &head_;
  44    }
  45  
  46    bool empty() const { return head_.next_ == &head_; }
  47    SnapshotImpl* oldest() const {
  48      assert(!empty());
  49      return head_.next_;
  50    }
  51    SnapshotImpl* newest() const {
  52      assert(!empty());
  53      return head_.prev_;
  54    }
  55  
  56    // Creates a SnapshotImpl and appends it to the end of the list.
  57    SnapshotImpl* New(SequenceNumber sequence_number) {
  58      assert(empty() || newest()->sequence_number_ <= sequence_number);
  59  
  60      SnapshotImpl* snapshot = new SnapshotImpl(sequence_number);
  61  
  62  #if !defined(NDEBUG)
  63      snapshot->list_ = this;
  64  #endif  // !defined(NDEBUG)
  65      snapshot->next_ = &head_;
  66      snapshot->prev_ = head_.prev_;
  67      snapshot->prev_->next_ = snapshot;
  68      snapshot->next_->prev_ = snapshot;
  69      return snapshot;
  70    }
  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    void Delete(const SnapshotImpl* snapshot) {
  80  #if !defined(NDEBUG)
  81      assert(snapshot->list_ == this);
  82  #endif  // !defined(NDEBUG)
  83      snapshot->prev_->next_ = snapshot->next_;
  84      snapshot->next_->prev_ = snapshot->prev_;
  85      delete snapshot;
  86    }
  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_
  96