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

Side by Side Diff: net/tools/dump_cache/dump_files.cc

Issue 12851: Disk cache: Add a tool to upgrade a set of cache files from one version to... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 12 years 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
« no previous file with comments | « net/tools/dump_cache/dump_cache.cc ('k') | net/tools/dump_cache/upgrade.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 // Copyright (c) 2008 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 // Performs basic inspection of the disk cache files with minimal disruption
6 // to the actual files (they still may change if an error is detected on the
7 // files).
8
9 #include <stdio.h>
10 #include <string>
11
12 #include "base/file_util.h"
13 #include "base/message_loop.h"
14 #include "net/base/file_stream.h"
15 #include "net/disk_cache/block_files.h"
16 #include "net/disk_cache/disk_format.h"
17 #include "net/disk_cache/mapped_file.h"
18 #include "net/disk_cache/storage_block.h"
19
20 namespace {
21
22 const wchar_t kIndexName[] = L"index";
23 const wchar_t kDataPrefix[] = L"data_";
24
25 // Reads the |header_size| bytes from the beginning of file |name|.
26 bool ReadHeader(const std::wstring name, char* header, int header_size) {
27 net::FileStream file;
28 file.Open(name, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
29 if (!file.IsOpen()) {
30 printf("Unable to open file %ls\n", name.c_str());
31 return false;
32 }
33
34 int read = file.Read(header, header_size, NULL);
35 if (read != header_size) {
36 printf("Unable to read file %ls\n", name.c_str());
37 return false;
38 }
39 return true;
40 }
41
42 int GetMajorVersionFromFile(const std::wstring name) {
43 disk_cache::IndexHeader header;
44 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header)))
45 return 0;
46
47 return header.version >> 16;
48 }
49
50 // Dumps the contents of the Index-file header.
51 void DumpIndexHeader(const std::wstring name) {
52 disk_cache::IndexHeader header;
53 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header)))
54 return;
55
56 printf("Index file:\n");
57 printf("magic: %x\n", header.magic);
58 printf("version: %d.%d\n", header.version >> 16, header.version & 0xffff);
59 printf("entries: %d\n", header.num_entries);
60 printf("total bytes: %d\n", header.num_bytes);
61 printf("last file number: %d\n", header.last_file);
62 printf("current id: %d\n", header.this_id);
63 printf("table length: %d\n", header.table_len);
64 printf("-------------------------\n\n");
65 }
66
67 // Dumps the contents of a block-file header.
68 void DumpBlockHeader(const std::wstring name) {
69 disk_cache::BlockFileHeader header;
70 if (!ReadHeader(name, reinterpret_cast<char*>(&header), sizeof(header)))
71 return;
72
73 std::wstring file_name = file_util::GetFilenameFromPath(name);
74
75 printf("Block file: %ls\n", file_name.c_str());
76 printf("magic: %x\n", header.magic);
77 printf("version: %d.%d\n", header.version >> 16, header.version & 0xffff);
78 printf("file id: %d\n", header.this_file);
79 printf("next file id: %d\n", header.next_file);
80 printf("entry size: %d\n", header.entry_size);
81 printf("current entries: %d\n", header.num_entries);
82 printf("max entries: %d\n", header.max_entries);
83 printf("updating: %d\n", header.updating);
84 printf("empty sz 1: %d\n", header.empty[0]);
85 printf("empty sz 2: %d\n", header.empty[1]);
86 printf("empty sz 3: %d\n", header.empty[2]);
87 printf("empty sz 4: %d\n", header.empty[3]);
88 printf("user 0: 0x%x\n", header.user[0]);
89 printf("user 1: 0x%x\n", header.user[1]);
90 printf("user 2: 0x%x\n", header.user[2]);
91 printf("user 3: 0x%x\n", header.user[3]);
92 printf("-------------------------\n\n");
93 }
94
95 // Simple class that interacts with the set of cache files.
96 class CacheDumper {
97 public:
98 explicit CacheDumper(const std::wstring path)
99 : path_(path), block_files_(path), index_(NULL) {}
100
101 bool Init();
102
103 // Reads an entry from disk. Return false when all entries have been already
104 // returned.
105 bool GetEntry(disk_cache::EntryStore* entry);
106
107 // Loads a specific block from the block files.
108 bool LoadEntry(disk_cache::CacheAddr addr, disk_cache::EntryStore* entry);
109 bool LoadRankings(disk_cache::CacheAddr addr,
110 disk_cache::RankingsNode* rankings);
111
112 private:
113 std::wstring path_;
114 disk_cache::BlockFiles block_files_;
115 scoped_refptr<disk_cache::MappedFile> index_file_;
116 disk_cache::Index* index_;
117 int current_hash_;
118 disk_cache::CacheAddr next_addr_;
119 DISALLOW_COPY_AND_ASSIGN(CacheDumper);
120 };
121
122 bool CacheDumper::Init() {
123 if (!block_files_.Init(false)) {
124 printf("Unable to init block files\n");
125 return false;
126 }
127
128 std::wstring index_name(path_);
129 file_util::AppendToPath(&index_name, kIndexName);
130 index_file_ = new disk_cache::MappedFile;
131 index_ =
132 reinterpret_cast<disk_cache::Index*>(index_file_->Init(index_name, 0));
133 if (!index_) {
134 printf("Unable to map index\n");
135 return false;
136 }
137
138 current_hash_ = 0;
139 next_addr_ = 0;
140 return true;
141 }
142
143 bool CacheDumper::GetEntry(disk_cache::EntryStore* entry) {
144 if (next_addr_) {
145 if (LoadEntry(next_addr_, entry)) {
146 next_addr_ = entry->next;
147 if (!next_addr_)
148 current_hash_++;
149 return true;
150 } else {
151 printf("Unable to load entry at address 0x%x\n", next_addr_);
152 next_addr_ = 0;
153 current_hash_++;
154 }
155 }
156
157 for (int i = current_hash_; i < index_->header.table_len; i++) {
158 // Yes, we'll crash if the table is shorter than expected, but only after
159 // dumping every entry that we can find.
160 if (index_->table[i]) {
161 current_hash_ = i;
162 if (LoadEntry(index_->table[i], entry)) {
163 next_addr_ = entry->next;
164 if (!next_addr_)
165 current_hash_++;
166 return true;
167 } else {
168 printf("Unable to load entry at address 0x%x\n", index_->table[i]);
169 }
170 }
171 }
172 return false;
173 }
174
175 bool CacheDumper::LoadEntry(disk_cache::CacheAddr addr,
176 disk_cache::EntryStore* entry) {
177 disk_cache::Addr address(addr);
178 disk_cache::MappedFile* file = block_files_.GetFile(address);
179 if (!file)
180 return false;
181
182 disk_cache::CacheEntryBlock entry_block(file, address);
183 if (!entry_block.Load())
184 return false;
185
186 memcpy(entry, entry_block.Data(), sizeof(*entry));
187 printf("Entry at 0x%x\n", addr);
188 return true;
189 }
190
191 bool CacheDumper::LoadRankings(disk_cache::CacheAddr addr,
192 disk_cache::RankingsNode* rankings) {
193 disk_cache::Addr address(addr);
194 disk_cache::MappedFile* file = block_files_.GetFile(address);
195 if (!file)
196 return false;
197
198 disk_cache::CacheRankingsBlock rank_block(file, address);
199 if (!rank_block.Load())
200 return false;
201
202 memcpy(rankings, rank_block.Data(), sizeof(*rankings));
203 printf("Rankings at 0x%x\n", addr);
204 return true;
205 }
206
207 void DumpEntry(const disk_cache::EntryStore& entry) {
208 std::string key;
209 if (!entry.long_key) {
210 key = entry.key;
211 if (key.size() > 50)
212 key.resize(50);
213 }
214
215 printf("hash: 0x%x\n", entry.hash);
216 printf("next entry: 0x%x\n", entry.next);
217 printf("rankings: 0x%x\n", entry.rankings_node);
218 printf("key length: %d\n", entry.key_len);
219 printf("key: \"%s\"\n", key.c_str());
220 printf("key addr: 0x%x\n", entry.long_key);
221 printf("data size 0: %d\n", entry.data_size[0]);
222 printf("data size 1: %d\n", entry.data_size[1]);
223 printf("data addr 0: 0x%x\n", entry.data_addr[0]);
224 printf("data addr 1: 0x%x\n", entry.data_addr[1]);
225 printf("----------\n\n");
226 }
227
228 void DumpRankings(const disk_cache::RankingsNode& rankings) {
229 printf("next: 0x%x\n", rankings.next);
230 printf("prev: 0x%x\n", rankings.prev);
231 printf("entry: 0x%x\n", rankings.contents);
232 printf("dirty: %d\n", rankings.dirty);
233 printf("pointer: 0x%x\n", rankings.pointer);
234 printf("----------\n\n");
235 }
236
237 } // namespace.
238
239 // -----------------------------------------------------------------------
240
241 int GetMajorVersion(const std::wstring input_path) {
242 std::wstring index_name(input_path);
243 file_util::AppendToPath(&index_name, kIndexName);
244
245 int version = GetMajorVersionFromFile(index_name);
246 if (!version)
247 return 0;
248
249 std::wstring data_name(input_path);
250 file_util::AppendToPath(&data_name, L"data_0");
251 if (version != GetMajorVersionFromFile(data_name))
252 return 0;
253
254 data_name = input_path;
255 file_util::AppendToPath(&data_name, L"data_1");
256 if (version != GetMajorVersionFromFile(data_name))
257 return 0;
258
259 return version;
260 }
261
262 // Dumps the headers of all files.
263 int DumpHeaders(const std::wstring input_path) {
264 std::wstring index_name(input_path);
265 file_util::AppendToPath(&index_name, kIndexName);
266 DumpIndexHeader(index_name);
267
268 std::wstring pattern(kDataPrefix);
269 pattern.append(L"*");
270 file_util::FileEnumerator iter(input_path, false,
271 file_util::FileEnumerator::FILES, pattern);
272 for (std::wstring file = iter.Next(); !file.empty(); file = iter.Next()) {
273 DumpBlockHeader(file);
274 }
275
276 return 0;
277 }
278
279 // Dumps all entries from the cache.
280 int DumpContents(const std::wstring input_path) {
281 DumpHeaders(input_path);
282
283 // We need a message loop, although we really don't run any task.
284 MessageLoop loop(MessageLoop::TYPE_IO);
285 CacheDumper dumper(input_path);
286 if (!dumper.Init())
287 return -1;
288
289 disk_cache::EntryStore entry;
290 while (dumper.GetEntry(&entry)) {
291 DumpEntry(entry);
292 disk_cache::RankingsNode rankings;
293 if (dumper.LoadRankings(entry.rankings_node, &rankings))
294 DumpRankings(rankings);
295 }
296
297 printf("Done.\n");
298
299 return 0;
300 }
OLDNEW
« no previous file with comments | « net/tools/dump_cache/dump_cache.cc ('k') | net/tools/dump_cache/upgrade.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698