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

Side by Side Diff: net/disk_cache/v3/block_bitmaps.cc

Issue 15203004: Disk cache: Reference CL for the implementation of file format version 3. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: IndexTable review Created 7 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/disk_cache/v3/block_bitmaps.h ('k') | net/disk_cache/v3/block_bitmaps_unittest.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) 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 "net/disk_cache/v3/block_bitmaps.h"
6
7 #include "base/metrics/histogram.h"
8 #include "base/string_util.h"
9 #include "base/stringprintf.h"
10 #include "base/threading/thread_checker.h"
11 #include "base/time.h"
12 #include "net/disk_cache/cache_util.h"
13 #include "net/disk_cache/disk_format_base.h"
14 #include "net/disk_cache/file_lock.h"
15 #include "net/disk_cache/trace.h"
16 #include "net/disk_cache/v3/backend_impl_v3.h"
17
18 using base::TimeTicks;
19
20 namespace disk_cache {
21
22 BlockBitmaps::BlockBitmaps(BackendImplV3* backend) : backend_(backend) {
23 }
24
25 BlockBitmaps::~BlockBitmaps() {
26 }
27
28 void BlockBitmaps::Init(const BlockFilesBitmaps& bitmaps) {
29 bitmaps_ = bitmaps;
30 for (int i = 0; i < kFirstAdditionalBlockFileV3; i++)
31 empty_counts_[i] = EmptyBlocksForType(i);
32 }
33
34 bool BlockBitmaps::CreateBlock(FileType block_type,
35 int block_count,
36 Addr* block_address) {
37 DCHECK_NE(block_type, EXTERNAL);
38 DCHECK_NE(block_type, RANKINGS);
39 if (block_count < 1 || block_count > kMaxNumBlocks)
40 return false;
41
42 int header_num = HeaderNumberForNewBlock(block_type, block_count);
43 if (header_num < 0)
44 return false;
45
46 int old_num_allocations = bitmaps_[header_num].MinimumAllocations();
47
48 int index;
49 if (!bitmaps_[header_num].CreateMapBlock(block_count, &index))
50 return false;
51
52 if (!index && (block_type == BLOCK_ENTRIES || block_type == BLOCK_EVICTED) &&
53 !bitmaps_[header_num].CreateMapBlock(block_count, &index)) {
54 // index 0 for entries is a reserved value.
55 return false;
56 }
57
58 // Yes, the count may be off by 1 when we start.
59 if (old_num_allocations != bitmaps_[header_num].MinimumAllocations())
60 empty_counts_[block_type]--;
61
62 if (empty_counts_[block_type] < (kNumExtraBlocks / kMaxNumBlocks) / 2)
63 backend_->GrowBlockFiles();
64
65 Addr address(block_type, block_count, bitmaps_[header_num].FileId(), index);
66 block_address->set_value(address.value());
67 Trace("CreateBlock 0x%x", address.value());
68 return true;
69 }
70
71 void BlockBitmaps::DeleteBlock(Addr address) {
72 if (!address.is_initialized() || address.is_separate_file())
73 return;
74
75 int header_num = GetHeaderNumber(address);
76 if (header_num < 0)
77 return;
78
79 Trace("DeleteBlock 0x%x", address.value());
80 bitmaps_[header_num].DeleteMapBlock(address.start_block(),
81 address.num_blocks());
82
83 //if (!bitmaps_[header_num].Header()->num_entries) {
84 // This file is now empty. Let's try to delete it.
85 //FileType type = Addr::RequiredFileType(header->entry_size);
86 //if (Addr::BlockSizeForFileType(RANKINGS) == header->entry_size)
87 // type = RANKINGS;
88 //RemoveEmptyFile(type); // Ignore failures.
89 //}
90 }
91
92 void BlockBitmaps::Clear() {
93 bitmaps_.clear();
94 }
95
96 void BlockBitmaps::ReportStats() {
97 int used_blocks[kFirstAdditionalBlockFile];
98 int load[kFirstAdditionalBlockFile];
99 for (int i = 0; i < kFirstAdditionalBlockFile; i++) {
100 GetFileStats(i, &used_blocks[i], &load[i]);
101 }
102 UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_0", used_blocks[0]);
103 UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_1", used_blocks[1]);
104 UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_2", used_blocks[2]);
105 UMA_HISTOGRAM_COUNTS("DiskCache.Blocks_3", used_blocks[3]);
106
107 UMA_HISTOGRAM_ENUMERATION("DiskCache.BlockLoad_0", load[0], 101);
108 UMA_HISTOGRAM_ENUMERATION("DiskCache.BlockLoad_1", load[1], 101);
109 UMA_HISTOGRAM_ENUMERATION("DiskCache.BlockLoad_2", load[2], 101);
110 UMA_HISTOGRAM_ENUMERATION("DiskCache.BlockLoad_3", load[3], 101);
111 }
112
113 bool BlockBitmaps::IsValid(Addr address) {
114 #ifdef NDEBUG
115 return true;
116 #else
117 if (!address.is_initialized() || address.is_separate_file())
118 return false;
119
120 int header_num = GetHeaderNumber(address);
121 if (header_num < 0)
122 return false;
123
124 bool rv = bitmaps_[header_num].UsedMapBlock(address.start_block(),
125 address.num_blocks());
126 DCHECK(rv);
127 return rv;
128 #endif
129 }
130
131 int BlockBitmaps::GetHeaderNumber(Addr address) {
132 DCHECK_GE(bitmaps_.size(), static_cast<size_t>(kFirstAdditionalBlockFileV3));
133 DCHECK(address.is_block_file() || !address.is_initialized());
134 if (!address.is_initialized())
135 return -1;
136
137 int file_index = address.FileNumber();
138 if (static_cast<unsigned int>(file_index) >= bitmaps_.size())
139 return -1;
140
141 return file_index;
142 }
143
144 int BlockBitmaps::EmptyBlocksForType(int next_file) {
145 int empty_blocks = 0;
146 do {
147 empty_blocks += bitmaps_[next_file].MinimumAllocations();
148 next_file = bitmaps_[next_file].NextFileId();
149 } while (next_file);
150 return empty_blocks;
151 }
152
153 int BlockBitmaps::HeaderNumberForNewBlock(FileType block_type,
154 int block_count) {
155 DCHECK_GT(block_type, 0);
156 int header_num = block_type - 1;
157 bool found = true;
158
159 TimeTicks start = TimeTicks::Now();
160 while (bitmaps_[header_num].NeedToGrowBlockFile(block_count)) {
161 header_num = bitmaps_[header_num].NextFileId();
162 if (!header_num) {
163 found = false;
164 break;
165 }
166 }
167
168 if (!found) {
169 // Restart the search, looking for any file with space. We know that all
170 // files of this type are low on free blocks, but we cannot grow any file
171 // at this time.
172 header_num = block_type - 1;
173 do {
174 if (bitmaps_[header_num].CanAllocate(block_count)) {
175 found = true; // Make sure file 0 is not mistaken with a failure.
176 break;
177 }
178 header_num = bitmaps_[header_num].NextFileId();
179 } while (header_num);
180
181 if (!found) {
182 NOTREACHED();
183 header_num = -1;
184 }
185 }
186
187 HISTOGRAM_TIMES("DiskCache.GetFileForNewBlock", TimeTicks::Now() - start);
188 return header_num;
189 }
190
191 // We are interested in the total number of blocks used by this file type, and
192 // the max number of blocks that we can store (reported as the percentage of
193 // used blocks). In order to find out the number of used blocks, we have to
194 // substract the empty blocks from the total blocks for each file in the chain.
195 void BlockBitmaps::GetFileStats(int index, int* used_count, int* load) {
196 int max_blocks = 0;
197 *used_count = 0;
198 *load = 0;
199 do {
200 int capacity = bitmaps_[index].Capacity();
201 int used = capacity - bitmaps_[index].EmptyBlocks();
202 DCHECK_GE(used, 0);
203
204 max_blocks += capacity;
205 *used_count += used;
206
207 index = bitmaps_[index].NextFileId();
208 } while (index);
209
210 if (max_blocks)
211 *load = *used_count * 100 / max_blocks;
212 }
213
214 } // namespace disk_cache
OLDNEW
« no previous file with comments | « net/disk_cache/v3/block_bitmaps.h ('k') | net/disk_cache/v3/block_bitmaps_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698