• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libjingle
3  * Copyright 2004--2005, Google Inc.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  *  1. Redistributions of source code must retain the above copyright notice,
9  *     this list of conditions and the following disclaimer.
10  *  2. Redistributions in binary form must reproduce the above copyright notice,
11  *     this list of conditions and the following disclaimer in the documentation
12  *     and/or other materials provided with the distribution.
13  *  3. The name of the author may not be used to endorse or promote products
14  *     derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 
28 #ifndef TALK_BASE_DISKCACHE_H__
29 #define TALK_BASE_DISKCACHE_H__
30 
31 #include <map>
32 #include <string>
33 
34 #ifdef WIN32
35 #undef UnlockResource
36 #endif  // WIN32
37 
38 namespace talk_base {
39 
40 class StreamInterface;
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 // DiskCache - An LRU cache of streams, stored on disk.
44 //
45 // Streams are identified by a unique resource id.  Multiple streams can be
46 // associated with each resource id, distinguished by an index.  When old
47 // resources are flushed from the cache, all streams associated with those
48 // resources are removed together.
49 // DiskCache is designed to persist across executions of the program.  It is
50 // safe for use from an arbitrary number of users on a single thread, but not
51 // from multiple threads or other processes.
52 ///////////////////////////////////////////////////////////////////////////////
53 
54 class DiskCache {
55 public:
56   DiskCache();
57   virtual ~DiskCache();
58 
59   bool Initialize(const std::string& folder, size_t size);
60   bool Purge();
61 
62   bool LockResource(const std::string& id);
63   StreamInterface* WriteResource(const std::string& id, size_t index);
64   bool UnlockResource(const std::string& id);
65 
66   StreamInterface* ReadResource(const std::string& id, size_t index) const;
67 
68   bool HasResource(const std::string& id) const;
69   bool HasResourceStream(const std::string& id, size_t index) const;
70   bool DeleteResource(const std::string& id);
71 
72  protected:
73   virtual bool InitializeEntries() = 0;
74   virtual bool PurgeFiles() = 0;
75 
76   virtual bool FileExists(const std::string& filename) const = 0;
77   virtual bool DeleteFile(const std::string& filename) const = 0;
78 
79   enum LockState { LS_UNLOCKED, LS_LOCKED, LS_UNLOCKING };
80   struct Entry {
81     LockState lock_state;
82     mutable size_t accessors;
83     size_t size;
84     size_t streams;
85     time_t last_modified;
86   };
87   typedef std::map<std::string, Entry> EntryMap;
88   friend class DiskCacheAdapter;
89 
90   bool CheckLimit();
91 
92   std::string IdToFilename(const std::string& id, size_t index) const;
93   bool FilenameToId(const std::string& filename, std::string* id,
94                     size_t* index) const;
95 
GetEntry(const std::string & id)96   const Entry* GetEntry(const std::string& id) const {
97     return const_cast<DiskCache*>(this)->GetOrCreateEntry(id, false);
98   }
99   Entry* GetOrCreateEntry(const std::string& id, bool create);
100 
101   void ReleaseResource(const std::string& id, size_t index) const;
102 
103   std::string folder_;
104   size_t max_cache_, total_size_;
105   EntryMap map_;
106   mutable size_t total_accessors_;
107 };
108 
109 ///////////////////////////////////////////////////////////////////////////////
110 // CacheLock - Automatically manage locking and unlocking, with optional
111 // rollback semantics
112 ///////////////////////////////////////////////////////////////////////////////
113 
114 class CacheLock {
115 public:
116   CacheLock(DiskCache* cache, const std::string& id, bool rollback = false)
cache_(cache)117   : cache_(cache), id_(id), rollback_(rollback)
118   {
119     locked_ = cache_->LockResource(id_);
120   }
~CacheLock()121   ~CacheLock() {
122     if (locked_) {
123       cache_->UnlockResource(id_);
124       if (rollback_) {
125         cache_->DeleteResource(id_);
126       }
127     }
128   }
IsLocked()129   bool IsLocked() const { return locked_; }
Commit()130   void Commit() { rollback_ = false; }
131 
132 private:
133   DiskCache* cache_;
134   std::string id_;
135   bool rollback_, locked_;
136 };
137 
138 ///////////////////////////////////////////////////////////////////////////////
139 
140 }  // namespace talk_base
141 
142 #endif // TALK_BASE_DISKCACHE_H__
143