Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: webkit/fileapi/file_system_usage_cache.cc

Issue 14895013: Move webkit/fileapi/file_system_mount_point_provider.h to webkit/browser/fileapi (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "webkit/fileapi/file_system_usage_cache.h"
6
7 #include <utility>
8
9 #include "base/debug/trace_event.h"
10 #include "base/file_util.h"
11 #include "base/files/file_path.h"
12 #include "base/pickle.h"
13 #include "base/stl_util.h"
14
15 namespace fileapi {
16
17 namespace {
18 const int64 kCloseDelaySeconds = 5;
19 const size_t kMaxHandleCacheSize = 2;
20 } // namespace
21
22 FileSystemUsageCache::FileSystemUsageCache(
23 base::SequencedTaskRunner* task_runner)
24 : weak_factory_(this),
25 task_runner_(task_runner) {
26 }
27
28 FileSystemUsageCache::~FileSystemUsageCache() {
29 task_runner_ = NULL;
30 CloseCacheFiles();
31 }
32
33 const base::FilePath::CharType FileSystemUsageCache::kUsageFileName[] =
34 FILE_PATH_LITERAL(".usage");
35 const char FileSystemUsageCache::kUsageFileHeader[] = "FSU5";
36 const int FileSystemUsageCache::kUsageFileHeaderSize = 4;
37
38 // Pickle::{Read,Write}Bool treat bool as int
39 const int FileSystemUsageCache::kUsageFileSize =
40 sizeof(Pickle::Header) +
41 FileSystemUsageCache::kUsageFileHeaderSize +
42 sizeof(int) + sizeof(int32) + sizeof(int64); // NOLINT
43
44 bool FileSystemUsageCache::GetUsage(const base::FilePath& usage_file_path,
45 int64* usage_out) {
46 TRACE_EVENT0("FileSystem", "UsageCache::GetUsage");
47 DCHECK(CalledOnValidThread());
48 DCHECK(usage_out);
49 bool is_valid = true;
50 uint32 dirty = 0;
51 int64 usage = 0;
52 if (!Read(usage_file_path, &is_valid, &dirty, &usage))
53 return false;
54 *usage_out = usage;
55 return true;
56 }
57
58 bool FileSystemUsageCache::GetDirty(const base::FilePath& usage_file_path,
59 uint32* dirty_out) {
60 TRACE_EVENT0("FileSystem", "UsageCache::GetDirty");
61 DCHECK(CalledOnValidThread());
62 DCHECK(dirty_out);
63 bool is_valid = true;
64 uint32 dirty = 0;
65 int64 usage = 0;
66 if (!Read(usage_file_path, &is_valid, &dirty, &usage))
67 return false;
68 *dirty_out = dirty;
69 return true;
70 }
71
72 bool FileSystemUsageCache::IncrementDirty(
73 const base::FilePath& usage_file_path) {
74 TRACE_EVENT0("FileSystem", "UsageCache::IncrementDirty");
75 DCHECK(CalledOnValidThread());
76 bool is_valid = true;
77 uint32 dirty = 0;
78 int64 usage = 0;
79 bool new_handle = !HasCacheFileHandle(usage_file_path);
80 if (!Read(usage_file_path, &is_valid, &dirty, &usage))
81 return false;
82
83 bool success = Write(usage_file_path, is_valid, dirty + 1, usage);
84 if (success && dirty == 0 && new_handle)
85 FlushFile(usage_file_path);
86 return success;
87 }
88
89 bool FileSystemUsageCache::DecrementDirty(
90 const base::FilePath& usage_file_path) {
91 TRACE_EVENT0("FileSystem", "UsageCache::DecrementDirty");
92 DCHECK(CalledOnValidThread());
93 bool is_valid = true;
94 uint32 dirty = 0;
95 int64 usage = 0;;
96 if (!Read(usage_file_path, &is_valid, &dirty, &usage) || dirty <= 0)
97 return false;
98
99 if (dirty <= 0)
100 return false;
101
102 return Write(usage_file_path, is_valid, dirty - 1, usage);
103 }
104
105 bool FileSystemUsageCache::Invalidate(const base::FilePath& usage_file_path) {
106 TRACE_EVENT0("FileSystem", "UsageCache::Invalidate");
107 DCHECK(CalledOnValidThread());
108 bool is_valid = true;
109 uint32 dirty = 0;
110 int64 usage = 0;
111 if (!Read(usage_file_path, &is_valid, &dirty, &usage))
112 return false;
113
114 return Write(usage_file_path, false, dirty, usage);
115 }
116
117 bool FileSystemUsageCache::IsValid(const base::FilePath& usage_file_path) {
118 TRACE_EVENT0("FileSystem", "UsageCache::IsValid");
119 DCHECK(CalledOnValidThread());
120 bool is_valid = true;
121 uint32 dirty = 0;
122 int64 usage = 0;
123 if (!Read(usage_file_path, &is_valid, &dirty, &usage))
124 return false;
125 return is_valid;
126 }
127
128 bool FileSystemUsageCache::AtomicUpdateUsageByDelta(
129 const base::FilePath& usage_file_path, int64 delta) {
130 TRACE_EVENT0("FileSystem", "UsageCache::AtomicUpdateUsageByDelta");
131 DCHECK(CalledOnValidThread());
132 bool is_valid = true;
133 uint32 dirty = 0;
134 int64 usage = 0;;
135 if (!Read(usage_file_path, &is_valid, &dirty, &usage))
136 return false;
137 return Write(usage_file_path, is_valid, dirty, usage + delta);
138 }
139
140 bool FileSystemUsageCache::UpdateUsage(const base::FilePath& usage_file_path,
141 int64 fs_usage) {
142 TRACE_EVENT0("FileSystem", "UsageCache::UpdateUsage");
143 DCHECK(CalledOnValidThread());
144 return Write(usage_file_path, true, 0, fs_usage);
145 }
146
147 bool FileSystemUsageCache::Exists(const base::FilePath& usage_file_path) {
148 TRACE_EVENT0("FileSystem", "UsageCache::Exists");
149 DCHECK(CalledOnValidThread());
150 return file_util::PathExists(usage_file_path);
151 }
152
153 bool FileSystemUsageCache::Delete(const base::FilePath& usage_file_path) {
154 TRACE_EVENT0("FileSystem", "UsageCache::Delete");
155 DCHECK(CalledOnValidThread());
156 CloseCacheFiles();
157 return file_util::Delete(usage_file_path, true);
158 }
159
160 void FileSystemUsageCache::CloseCacheFiles() {
161 TRACE_EVENT0("FileSystem", "UsageCache::CloseCacheFiles");
162 DCHECK(CalledOnValidThread());
163 for (CacheFiles::iterator itr = cache_files_.begin();
164 itr != cache_files_.end(); ++itr) {
165 if (itr->second != base::kInvalidPlatformFileValue)
166 base::ClosePlatformFile(itr->second);
167 }
168 cache_files_.clear();
169 timer_.Stop();
170 }
171
172 bool FileSystemUsageCache::Read(const base::FilePath& usage_file_path,
173 bool* is_valid,
174 uint32* dirty_out,
175 int64* usage_out) {
176 TRACE_EVENT0("FileSystem", "UsageCache::Read");
177 DCHECK(CalledOnValidThread());
178 DCHECK(is_valid);
179 DCHECK(dirty_out);
180 DCHECK(usage_out);
181 char buffer[kUsageFileSize];
182 const char *header;
183 if (usage_file_path.empty() ||
184 !ReadBytes(usage_file_path, buffer, kUsageFileSize))
185 return false;
186 Pickle read_pickle(buffer, kUsageFileSize);
187 PickleIterator iter(read_pickle);
188 uint32 dirty = 0;
189 int64 usage = 0;
190
191 if (!read_pickle.ReadBytes(&iter, &header, kUsageFileHeaderSize) ||
192 !read_pickle.ReadBool(&iter, is_valid) ||
193 !read_pickle.ReadUInt32(&iter, &dirty) ||
194 !read_pickle.ReadInt64(&iter, &usage))
195 return false;
196
197 if (header[0] != kUsageFileHeader[0] ||
198 header[1] != kUsageFileHeader[1] ||
199 header[2] != kUsageFileHeader[2] ||
200 header[3] != kUsageFileHeader[3])
201 return false;
202
203 *dirty_out = dirty;
204 *usage_out = usage;
205 return true;
206 }
207
208 bool FileSystemUsageCache::Write(const base::FilePath& usage_file_path,
209 bool is_valid,
210 int32 dirty,
211 int64 usage) {
212 TRACE_EVENT0("FileSystem", "UsageCache::Write");
213 DCHECK(CalledOnValidThread());
214 Pickle write_pickle;
215 write_pickle.WriteBytes(kUsageFileHeader, kUsageFileHeaderSize);
216 write_pickle.WriteBool(is_valid);
217 write_pickle.WriteUInt32(dirty);
218 write_pickle.WriteInt64(usage);
219
220 if (!WriteBytes(usage_file_path,
221 static_cast<const char*>(write_pickle.data()),
222 write_pickle.size())) {
223 Delete(usage_file_path);
224 return false;
225 }
226 return true;
227 }
228
229 bool FileSystemUsageCache::GetPlatformFile(const base::FilePath& file_path,
230 base::PlatformFile* file) {
231 DCHECK(CalledOnValidThread());
232 if (cache_files_.size() >= kMaxHandleCacheSize)
233 CloseCacheFiles();
234 ScheduleCloseTimer();
235
236 std::pair<CacheFiles::iterator, bool> inserted =
237 cache_files_.insert(
238 std::make_pair(file_path, base::kInvalidPlatformFileValue));
239 if (!inserted.second) {
240 *file = inserted.first->second;
241 return true;
242 }
243
244 base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
245 base::PlatformFile platform_file =
246 base::CreatePlatformFile(file_path,
247 base::PLATFORM_FILE_OPEN_ALWAYS |
248 base::PLATFORM_FILE_READ |
249 base::PLATFORM_FILE_WRITE,
250 NULL, &error);
251 if (error != base::PLATFORM_FILE_OK) {
252 cache_files_.erase(inserted.first);
253 return false;
254 }
255
256 inserted.first->second = platform_file;
257 *file = platform_file;
258 return true;
259 }
260
261 bool FileSystemUsageCache::ReadBytes(const base::FilePath& file_path,
262 char* buffer,
263 int64 buffer_size) {
264 DCHECK(CalledOnValidThread());
265 base::PlatformFile file;
266 if (!GetPlatformFile(file_path, &file))
267 return false;
268 return base::ReadPlatformFile(file, 0, buffer, buffer_size) == buffer_size;
269 }
270
271 bool FileSystemUsageCache::WriteBytes(const base::FilePath& file_path,
272 const char* buffer,
273 int64 buffer_size) {
274 DCHECK(CalledOnValidThread());
275 base::PlatformFile file;
276 if (!GetPlatformFile(file_path, &file))
277 return false;
278 return base::WritePlatformFile(file, 0, buffer, buffer_size) == buffer_size;
279 }
280
281 bool FileSystemUsageCache::FlushFile(const base::FilePath& file_path) {
282 TRACE_EVENT0("FileSystem", "UsageCache::FlushFile");
283 DCHECK(CalledOnValidThread());
284 base::PlatformFile file = base::kInvalidPlatformFileValue;
285 return GetPlatformFile(file_path, &file) && base::FlushPlatformFile(file);
286 }
287
288 void FileSystemUsageCache::ScheduleCloseTimer() {
289 DCHECK(CalledOnValidThread());
290 if (timer_.IsRunning()) {
291 timer_.Reset();
292 return;
293 }
294
295 timer_.Start(FROM_HERE,
296 base::TimeDelta::FromSeconds(kCloseDelaySeconds),
297 base::Bind(&FileSystemUsageCache::CloseCacheFiles,
298 weak_factory_.GetWeakPtr()));
299 }
300
301 bool FileSystemUsageCache::CalledOnValidThread() {
302 return !task_runner_ || task_runner_->RunsTasksOnCurrentThread();
303 }
304
305 bool FileSystemUsageCache::HasCacheFileHandle(const base::FilePath& file_path) {
306 DCHECK(CalledOnValidThread());
307 DCHECK_LE(cache_files_.size(), kMaxHandleCacheSize);
308 return ContainsKey(cache_files_, file_path);
309 }
310
311 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698