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
21namespace rtc {
22
23class 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
37class DiskCache {
38public:
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
97class CacheLock {
98public:
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
115private:
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