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

Side by Side Diff: chrome/browser/policy/resource_cache.cc

Issue 12189011: Split up chrome/browser/policy subdirectory (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase, add chrome/browser/chromeos/policy/OWNERS Created 7 years, 9 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) 2013 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 "chrome/browser/policy/resource_cache.h"
6
7 #include <string.h>
8
9 #include "base/file_util.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/string_util.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "base/threading/thread_restrictions.h"
15 #include "third_party/leveldatabase/src/include/leveldb/db.h"
16 #include "third_party/leveldatabase/src/include/leveldb/iterator.h"
17 #include "third_party/leveldatabase/src/include/leveldb/options.h"
18 #include "third_party/leveldatabase/src/include/leveldb/slice.h"
19 #include "third_party/leveldatabase/src/include/leveldb/status.h"
20 #include "third_party/leveldatabase/src/include/leveldb/write_batch.h"
21
22 namespace policy {
23
24 ResourceCache::ResourceCache(const base::FilePath& cache_path) {
25 // Allow the cache to be created in a different thread than the thread that's
26 // going to use it.
27 DetachFromThread();
28
29 file_util::CreateDirectory(cache_path.DirName());
30 leveldb::Options options;
31 options.create_if_missing = true;
32 leveldb::DB* db = NULL;
33 leveldb::Status status =
34 leveldb::DB::Open(options, cache_path.AsUTF8Unsafe(), &db);
35 if (!status.ok()) {
36 LOG(WARNING) << "Failed to open leveldb at " << cache_path.AsUTF8Unsafe()
37 << ": " << status.ToString();
38 // Maybe the database is busted; drop everything and try to create it again.
39 file_util::Delete(cache_path, true);
40 status = leveldb::DB::Open(options, cache_path.AsUTF8Unsafe(), &db);
41
42 if (!status.ok())
43 LOG(WARNING) << "Failed to open a new leveldb after wiping: "
44 << status.ToString();
45 }
46 db_.reset(db);
47 }
48
49 ResourceCache::~ResourceCache() {
50 DCHECK(CalledOnValidThread());
51 }
52
53 bool ResourceCache::Store(const std::string& key,
54 const std::string& subkey,
55 const std::string& data) {
56 DCHECK(CalledOnValidThread());
57 base::ThreadRestrictions::AssertIOAllowed();
58
59 if (!IsOpen())
60 return false;
61
62 std::string path(CreatePath(key, subkey));
63 return db_->Put(leveldb::WriteOptions(), path, data).ok();
64 }
65
66 bool ResourceCache::Load(const std::string& key,
67 const std::string& subkey,
68 std::string* data) {
69 DCHECK(CalledOnValidThread());
70 base::ThreadRestrictions::AssertIOAllowed();
71 if (!IsOpen())
72 return false;
73
74 leveldb::ReadOptions options;
75 options.fill_cache = false;
76 std::string path(CreatePath(key, subkey));
77 return db_->Get(options, path, data).ok();
78 }
79
80 void ResourceCache::LoadAllSubkeys(
81 const std::string& key,
82 std::map<std::string, std::string>* contents) {
83 DCHECK(CalledOnValidThread());
84 base::ThreadRestrictions::AssertIOAllowed();
85 if (!IsOpen())
86 return;
87
88 contents->clear();
89
90 const std::string prefix(CreatePathPrefix(key));
91 leveldb::ReadOptions options;
92 options.fill_cache = false;
93 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options));
94 for (it->Seek(prefix); it->Valid(); it->Next()) {
95 if (!it->key().starts_with(prefix))
96 break;
97 const std::string subkey(GetSubkey(it->key().ToString()));
98 leveldb::Slice slice = it->value();
99 (*contents)[subkey].assign(slice.data(), slice.size());
100 }
101 }
102
103 void ResourceCache::Delete(const std::string& key, const std::string& subkey) {
104 DCHECK(CalledOnValidThread());
105 base::ThreadRestrictions::AssertIOAllowed();
106 if (!IsOpen())
107 return;
108
109 const std::string path(CreatePath(key, subkey));
110 leveldb::Status status = db_->Delete(leveldb::WriteOptions(), path);
111 if (!status.ok()) {
112 LOG(WARNING) << "Failed to Delete \"" << path << "\" from leveldb: "
113 << status.ToString();
114 }
115 }
116
117 void ResourceCache::PurgeOtherSubkeys(
118 const std::string& key,
119 const std::set<std::string>& subkeys_to_keep) {
120 DCHECK(CalledOnValidThread());
121 base::ThreadRestrictions::AssertIOAllowed();
122 if (!IsOpen())
123 return;
124
125 leveldb::WriteBatch batch;
126 const std::string prefix(CreatePathPrefix(key));
127 leveldb::ReadOptions options;
128 options.fill_cache = false;
129 scoped_ptr<leveldb::Iterator> it(db_->NewIterator(options));
130 for (it->Seek(prefix); it->Valid(); it->Next()) {
131 if (!it->key().starts_with(prefix))
132 break;
133 const std::string subkey(GetSubkey(it->key().ToString()));
134 if (subkeys_to_keep.find(subkey) == subkeys_to_keep.end())
135 batch.Delete(it->key());
136 }
137
138 leveldb::Status status = db_->Write(leveldb::WriteOptions(), &batch);
139 if (!status.ok()) {
140 LOG(WARNING) << "Purge of leveldb subkeys of " << key << " failed: "
141 << status.ToString();
142 }
143 }
144
145 std::string ResourceCache::GetStringWithPrefix(const std::string& s) {
146 char buffer[sizeof(size_t)];
147 size_t size = s.size();
148 memcpy(buffer, &size, sizeof(size_t));
149 return std::string(buffer, sizeof(size_t)) + s;
150 }
151
152 std::string ResourceCache::CreatePathPrefix(const std::string& key) {
153 return GetStringWithPrefix(key);
154 }
155
156 std::string ResourceCache::CreatePath(const std::string& key,
157 const std::string& subkey) {
158 return GetStringWithPrefix(key) + GetStringWithPrefix(subkey);
159 }
160
161 std::string ResourceCache::GetSubkey(const std::string& path) {
162 // |path| was produced by CreatePath(). Skip the first key, then skip the
163 // size of the subkey.
164 if (path.size() < sizeof(size_t)) {
165 NOTREACHED();
166 return EmptyString();
167 }
168
169 // Skip the first string. |offset| is the start of the second string,
170 // immediately preceded by its size.
171 const size_t* size = reinterpret_cast<const size_t*>(path.data());
172 size_t offset = sizeof(size_t) + *size + sizeof(size_t);
173 if (path.size() < offset) {
174 NOTREACHED();
175 return EmptyString();
176 }
177
178 // Skip the size of the second string.
179 size = reinterpret_cast<const size_t*>(path.data() + offset - sizeof(size_t));
180 if (*size != path.size() - offset) {
181 NOTREACHED();
182 return EmptyString();
183 }
184
185 return path.substr(offset, *size);
186 }
187
188 } // namespace policy
OLDNEW
« no previous file with comments | « chrome/browser/policy/resource_cache.h ('k') | chrome/browser/policy/resource_cache_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698