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 
GetEntry(const std::string & id)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)
cache_(cache)100   : cache_(cache), id_(id), rollback_(rollback)
101   {
102     locked_ = cache_->LockResource(id_);
103   }
~CacheLock()104   ~CacheLock() {
105     if (locked_) {
106       cache_->UnlockResource(id_);
107       if (rollback_) {
108         cache_->DeleteResource(id_);
109       }
110     }
111   }
IsLocked()112   bool IsLocked() const { return locked_; }
Commit()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