Home | History | Annotate | Download | only in base
      1 /*
      2  *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #ifndef WEBRTC_BASE_DISKCACHE_H__
     12 #define WEBRTC_BASE_DISKCACHE_H__
     13 
     14 #include <map>
     15 #include <string>
     16 
     17 #if defined(WEBRTC_WIN)
     18 #undef UnlockResource
     19 #endif  // WEBRTC_WIN
     20 
     21 namespace rtc {
     22 
     23 class StreamInterface;
     24 
     25 ///////////////////////////////////////////////////////////////////////////////
     26 // DiskCache - An LRU cache of streams, stored on disk.
     27 //
     28 // Streams are identified by a unique resource id.  Multiple streams can be
     29 // associated with each resource id, distinguished by an index.  When old
     30 // resources are flushed from the cache, all streams associated with those
     31 // resources are removed together.
     32 // DiskCache is designed to persist across executions of the program.  It is
     33 // safe for use from an arbitrary number of users on a single thread, but not
     34 // from multiple threads or other processes.
     35 ///////////////////////////////////////////////////////////////////////////////
     36 
     37 class DiskCache {
     38 public:
     39   DiskCache();
     40   virtual ~DiskCache();
     41 
     42   bool Initialize(const std::string& folder, size_t size);
     43   bool Purge();
     44 
     45   bool LockResource(const std::string& id);
     46   StreamInterface* WriteResource(const std::string& id, size_t index);
     47   bool UnlockResource(const std::string& id);
     48 
     49   StreamInterface* ReadResource(const std::string& id, size_t index) const;
     50 
     51   bool HasResource(const std::string& id) const;
     52   bool HasResourceStream(const std::string& id, size_t index) const;
     53   bool DeleteResource(const std::string& id);
     54 
     55  protected:
     56   virtual bool InitializeEntries() = 0;
     57   virtual bool PurgeFiles() = 0;
     58 
     59   virtual bool FileExists(const std::string& filename) const = 0;
     60   virtual bool DeleteFile(const std::string& filename) const = 0;
     61 
     62   enum LockState { LS_UNLOCKED, LS_LOCKED, LS_UNLOCKING };
     63   struct Entry {
     64     LockState lock_state;
     65     mutable size_t accessors;
     66     size_t size;
     67     size_t streams;
     68     time_t last_modified;
     69   };
     70   typedef std::map<std::string, Entry> EntryMap;
     71   friend class DiskCacheAdapter;
     72 
     73   bool CheckLimit();
     74 
     75   std::string IdToFilename(const std::string& id, size_t index) const;
     76   bool FilenameToId(const std::string& filename, std::string* id,
     77                     size_t* index) const;
     78 
     79   const Entry* GetEntry(const std::string& id) const {
     80     return const_cast<DiskCache*>(this)->GetOrCreateEntry(id, false);
     81   }
     82   Entry* GetOrCreateEntry(const std::string& id, bool create);
     83 
     84   void ReleaseResource(const std::string& id, size_t index) const;
     85 
     86   std::string folder_;
     87   size_t max_cache_, total_size_;
     88   EntryMap map_;
     89   mutable size_t total_accessors_;
     90 };
     91 
     92 ///////////////////////////////////////////////////////////////////////////////
     93 // CacheLock - Automatically manage locking and unlocking, with optional
     94 // rollback semantics
     95 ///////////////////////////////////////////////////////////////////////////////
     96 
     97 class CacheLock {
     98 public:
     99   CacheLock(DiskCache* cache, const std::string& id, bool rollback = false)
    100   : cache_(cache), id_(id), rollback_(rollback)
    101   {
    102     locked_ = cache_->LockResource(id_);
    103   }
    104   ~CacheLock() {
    105     if (locked_) {
    106       cache_->UnlockResource(id_);
    107       if (rollback_) {
    108         cache_->DeleteResource(id_);
    109       }
    110     }
    111   }
    112   bool IsLocked() const { return locked_; }
    113   void Commit() { rollback_ = false; }
    114 
    115 private:
    116   DiskCache* cache_;
    117   std::string id_;
    118   bool rollback_, locked_;
    119 };
    120 
    121 ///////////////////////////////////////////////////////////////////////////////
    122 
    123 }  // namespace rtc
    124 
    125 #endif // WEBRTC_BASE_DISKCACHE_H__
    126