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