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

Side by Side Diff: net/disk_cache/blockfile/rankings.cc

Issue 266243004: Clang format slam. Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/disk_cache/blockfile/rankings.h" 5 #include "net/disk_cache/blockfile/rankings.h"
6 6
7 #include "base/metrics/histogram.h" 7 #include "base/metrics/histogram.h"
8 #include "net/disk_cache/blockfile/backend_impl.h" 8 #include "net/disk_cache/blockfile/backend_impl.h"
9 #include "net/disk_cache/blockfile/disk_format.h" 9 #include "net/disk_cache/blockfile/disk_format.h"
10 #include "net/disk_cache/blockfile/entry_impl.h" 10 #include "net/disk_cache/blockfile/entry_impl.h"
11 #include "net/disk_cache/blockfile/errors.h" 11 #include "net/disk_cache/blockfile/errors.h"
12 #include "net/disk_cache/blockfile/histogram_macros.h" 12 #include "net/disk_cache/blockfile/histogram_macros.h"
13 #include "net/disk_cache/blockfile/stress_support.h" 13 #include "net/disk_cache/blockfile/stress_support.h"
14 14
15 // Provide a BackendImpl object to macros from histogram_macros.h. 15 // Provide a BackendImpl object to macros from histogram_macros.h.
16 #define CACHE_UMA_BACKEND_IMPL_OBJ backend_ 16 #define CACHE_UMA_BACKEND_IMPL_OBJ backend_
17 17
18 using base::Time; 18 using base::Time;
19 using base::TimeTicks; 19 using base::TimeTicks;
20 20
21 namespace disk_cache { 21 namespace disk_cache {
22 // This is used by crash_cache.exe to generate unit test files. 22 // This is used by crash_cache.exe to generate unit test files.
23 NET_EXPORT_PRIVATE RankCrashes g_rankings_crash = NO_CRASH; 23 NET_EXPORT_PRIVATE RankCrashes g_rankings_crash = NO_CRASH;
24 } 24 }
25 25
26 namespace { 26 namespace {
27 27
28 enum Operation { 28 enum Operation { INSERT = 1, REMOVE };
29 INSERT = 1,
30 REMOVE
31 };
32 29
33 // This class provides a simple lock for the LRU list of rankings. Whenever an 30 // This class provides a simple lock for the LRU list of rankings. Whenever an
34 // entry is to be inserted or removed from the list, a transaction object should 31 // entry is to be inserted or removed from the list, a transaction object should
35 // be created to keep track of the operation. If the process crashes before 32 // be created to keep track of the operation. If the process crashes before
36 // finishing the operation, the transaction record (stored as part of the user 33 // finishing the operation, the transaction record (stored as part of the user
37 // data on the file header) can be used to finish the operation. 34 // data on the file header) can be used to finish the operation.
38 class Transaction { 35 class Transaction {
39 public: 36 public:
40 // addr is the cache addres of the node being inserted or removed. We want to 37 // addr is the cache addres of the node being inserted or removed. We want to
41 // avoid having the compiler doing optimizations on when to read or write 38 // avoid having the compiler doing optimizations on when to read or write
42 // from user_data because it is the basis of the crash detection. Maybe 39 // from user_data because it is the basis of the crash detection. Maybe
43 // volatile is not enough for that, but it should be a good hint. 40 // volatile is not enough for that, but it should be a good hint.
44 Transaction(volatile disk_cache::LruData* data, disk_cache::Addr addr, 41 Transaction(volatile disk_cache::LruData* data,
45 Operation op, int list); 42 disk_cache::Addr addr,
43 Operation op,
44 int list);
46 ~Transaction(); 45 ~Transaction();
46
47 private: 47 private:
48 volatile disk_cache::LruData* data_; 48 volatile disk_cache::LruData* data_;
49 DISALLOW_COPY_AND_ASSIGN(Transaction); 49 DISALLOW_COPY_AND_ASSIGN(Transaction);
50 }; 50 };
51 51
52 Transaction::Transaction(volatile disk_cache::LruData* data, 52 Transaction::Transaction(volatile disk_cache::LruData* data,
53 disk_cache::Addr addr, Operation op, int list) 53 disk_cache::Addr addr,
54 Operation op,
55 int list)
54 : data_(data) { 56 : data_(data) {
55 DCHECK(!data_->transaction); 57 DCHECK(!data_->transaction);
56 DCHECK(addr.is_initialized()); 58 DCHECK(addr.is_initialized());
57 data_->operation = op; 59 data_->operation = op;
58 data_->operation_list = list; 60 data_->operation_list = list;
59 data_->transaction = addr.value(); 61 data_->transaction = addr.value();
60 } 62 }
61 63
62 Transaction::~Transaction() { 64 Transaction::~Transaction() {
63 DCHECK(data_->transaction); 65 DCHECK(data_->transaction);
64 data_->transaction = 0; 66 data_->transaction = 0;
65 data_->operation = 0; 67 data_->operation = 0;
66 data_->operation_list = 0; 68 data_->operation_list = 0;
67 } 69 }
68 70
69 // Code locations that can generate crashes. 71 // Code locations that can generate crashes.
70 enum CrashLocation { 72 enum CrashLocation {
71 ON_INSERT_1, ON_INSERT_2, ON_INSERT_3, ON_INSERT_4, ON_REMOVE_1, ON_REMOVE_2, 73 ON_INSERT_1,
72 ON_REMOVE_3, ON_REMOVE_4, ON_REMOVE_5, ON_REMOVE_6, ON_REMOVE_7, ON_REMOVE_8 74 ON_INSERT_2,
75 ON_INSERT_3,
76 ON_INSERT_4,
77 ON_REMOVE_1,
78 ON_REMOVE_2,
79 ON_REMOVE_3,
80 ON_REMOVE_4,
81 ON_REMOVE_5,
82 ON_REMOVE_6,
83 ON_REMOVE_7,
84 ON_REMOVE_8
73 }; 85 };
74 86
75 #ifndef NDEBUG 87 #ifndef NDEBUG
76 void TerminateSelf() { 88 void TerminateSelf() {
77 #if defined(OS_WIN) 89 #if defined(OS_WIN)
78 // Windows does more work on _exit() than we would like, so we force exit. 90 // Windows does more work on _exit() than we would like, so we force exit.
79 TerminateProcess(GetCurrentProcess(), 0); 91 TerminateProcess(GetCurrentProcess(), 0);
80 #elif defined(OS_POSIX) 92 #elif defined(OS_POSIX)
81 // On POSIX, _exit() will terminate the process with minimal cleanup, 93 // On POSIX, _exit() will terminate the process with minimal cleanup,
82 // and it is cleaner than killing. 94 // and it is cleaner than killing.
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
186 base::Time now = base::Time::Now(); 198 base::Time now = base::Time::Now();
187 node->Data()->last_used = now.ToInternalValue(); 199 node->Data()->last_used = now.ToInternalValue();
188 if (modified) 200 if (modified)
189 node->Data()->last_modified = now.ToInternalValue(); 201 node->Data()->last_modified = now.ToInternalValue();
190 } 202 }
191 203
192 } // namespace 204 } // namespace
193 205
194 namespace disk_cache { 206 namespace disk_cache {
195 207
196 Rankings::ScopedRankingsBlock::ScopedRankingsBlock() : rankings_(NULL) {} 208 Rankings::ScopedRankingsBlock::ScopedRankingsBlock() : rankings_(NULL) {
209 }
197 210
198 Rankings::ScopedRankingsBlock::ScopedRankingsBlock(Rankings* rankings) 211 Rankings::ScopedRankingsBlock::ScopedRankingsBlock(Rankings* rankings)
199 : rankings_(rankings) {} 212 : rankings_(rankings) {
213 }
200 214
201 Rankings::ScopedRankingsBlock::ScopedRankingsBlock( 215 Rankings::ScopedRankingsBlock::ScopedRankingsBlock(Rankings* rankings,
202 Rankings* rankings, CacheRankingsBlock* node) 216 CacheRankingsBlock* node)
203 : scoped_ptr<CacheRankingsBlock>(node), rankings_(rankings) {} 217 : scoped_ptr<CacheRankingsBlock>(node), rankings_(rankings) {
218 }
204 219
205 Rankings::Iterator::Iterator(Rankings* rankings) { 220 Rankings::Iterator::Iterator(Rankings* rankings) {
206 memset(this, 0, sizeof(Iterator)); 221 memset(this, 0, sizeof(Iterator));
207 my_rankings = rankings; 222 my_rankings = rankings;
208 } 223 }
209 224
210 Rankings::Iterator::~Iterator() { 225 Rankings::Iterator::~Iterator() {
211 for (int i = 0; i < 3; i++) 226 for (int i = 0; i < 3; i++)
212 ScopedRankingsBlock(my_rankings, nodes[i]); 227 ScopedRankingsBlock(my_rankings, nodes[i]);
213 } 228 }
214 229
215 Rankings::Rankings() : init_(false) {} 230 Rankings::Rankings() : init_(false) {
231 }
216 232
217 Rankings::~Rankings() {} 233 Rankings::~Rankings() {
234 }
218 235
219 bool Rankings::Init(BackendImpl* backend, bool count_lists) { 236 bool Rankings::Init(BackendImpl* backend, bool count_lists) {
220 DCHECK(!init_); 237 DCHECK(!init_);
221 if (init_) 238 if (init_)
222 return false; 239 return false;
223 240
224 backend_ = backend; 241 backend_ = backend;
225 control_data_ = backend_->GetLruData(); 242 control_data_ = backend_->GetLruData();
226 count_lists_ = count_lists; 243 count_lists_ = count_lists;
227 244
(...skipping 20 matching lines...) Expand all
248 Trace("Insert 0x%x l %d", node->address().value(), list); 265 Trace("Insert 0x%x l %d", node->address().value(), list);
249 DCHECK(node->HasData()); 266 DCHECK(node->HasData());
250 Addr& my_head = heads_[list]; 267 Addr& my_head = heads_[list];
251 Addr& my_tail = tails_[list]; 268 Addr& my_tail = tails_[list];
252 Transaction lock(control_data_, node->address(), INSERT, list); 269 Transaction lock(control_data_, node->address(), INSERT, list);
253 CacheRankingsBlock head(backend_->File(my_head), my_head); 270 CacheRankingsBlock head(backend_->File(my_head), my_head);
254 if (my_head.is_initialized()) { 271 if (my_head.is_initialized()) {
255 if (!GetRanking(&head)) 272 if (!GetRanking(&head))
256 return; 273 return;
257 274
258 if (head.Data()->prev != my_head.value() && // Normal path. 275 if (head.Data()->prev != my_head.value() && // Normal path.
259 head.Data()->prev != node->address().value()) { // FinishInsert(). 276 head.Data()->prev != node->address().value()) { // FinishInsert().
260 backend_->CriticalError(ERR_INVALID_LINKS); 277 backend_->CriticalError(ERR_INVALID_LINKS);
261 return; 278 return;
262 } 279 }
263 280
264 head.Data()->prev = node->address().value(); 281 head.Data()->prev = node->address().value();
265 head.Store(); 282 head.Store();
266 GenerateCrash(ON_INSERT_1); 283 GenerateCrash(ON_INSERT_1);
267 UpdateIterators(&head); 284 UpdateIterators(&head);
268 } 285 }
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
309 // 2. r(r, b), b(r, y), head(b), tail(y) WriteHead() 326 // 2. r(r, b), b(r, y), head(b), tail(y) WriteHead()
310 // 3. r(r, b), b(b, y), head(b), tail(y) next.Store() 327 // 3. r(r, b), b(b, y), head(b), tail(y) next.Store()
311 // 4. r(0, 0), b(b, y), head(b), tail(y) prev.Store() 328 // 4. r(0, 0), b(b, y), head(b), tail(y) prev.Store()
312 // 329 //
313 // D. Remove tail: 330 // D. Remove tail:
314 // 1. a(x, r), r(a, r), head(x), tail(r) initial state 331 // 1. a(x, r), r(a, r), head(x), tail(r) initial state
315 // 2. a(x, r), r(a, r), head(x), tail(a) WriteTail() 332 // 2. a(x, r), r(a, r), head(x), tail(a) WriteTail()
316 // 3. a(x, a), r(a, r), head(x), tail(a) prev.Store() 333 // 3. a(x, a), r(a, r), head(x), tail(a) prev.Store()
317 // 4. a(x, a), r(0, 0), head(x), tail(a) next.Store() 334 // 4. a(x, a), r(0, 0), head(x), tail(a) next.Store()
318 void Rankings::Remove(CacheRankingsBlock* node, List list, bool strict) { 335 void Rankings::Remove(CacheRankingsBlock* node, List list, bool strict) {
319 Trace("Remove 0x%x (0x%x 0x%x) l %d", node->address().value(), 336 Trace("Remove 0x%x (0x%x 0x%x) l %d",
320 node->Data()->next, node->Data()->prev, list); 337 node->address().value(),
338 node->Data()->next,
339 node->Data()->prev,
340 list);
321 DCHECK(node->HasData()); 341 DCHECK(node->HasData());
322 if (strict) 342 if (strict)
323 InvalidateIterators(node); 343 InvalidateIterators(node);
324 344
325 Addr next_addr(node->Data()->next); 345 Addr next_addr(node->Data()->next);
326 Addr prev_addr(node->Data()->prev); 346 Addr prev_addr(node->Data()->prev);
327 if (!next_addr.is_initialized() || next_addr.is_separate_file() || 347 if (!next_addr.is_initialized() || next_addr.is_separate_file() ||
328 !prev_addr.is_initialized() || prev_addr.is_separate_file()) { 348 !prev_addr.is_initialized() || prev_addr.is_separate_file()) {
329 if (next_addr.is_initialized() || prev_addr.is_initialized()) { 349 if (next_addr.is_initialized() || prev_addr.is_initialized()) {
330 LOG(ERROR) << "Invalid rankings info."; 350 LOG(ERROR) << "Invalid rankings info.";
(...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after
735 WriteTail(my_list); 755 WriteTail(my_list);
736 } 756 }
737 757
738 next.Store(); 758 next.Store();
739 prev.Store(); 759 prev.Store();
740 control_data_->transaction = 0; 760 control_data_->transaction = 0;
741 control_data_->operation = 0; 761 control_data_->operation = 0;
742 backend_->FlushIndex(); 762 backend_->FlushIndex();
743 } 763 }
744 764
745 bool Rankings::CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, 765 bool Rankings::CheckLinks(CacheRankingsBlock* node,
746 CacheRankingsBlock* next, List* list) { 766 CacheRankingsBlock* prev,
767 CacheRankingsBlock* next,
768 List* list) {
747 CacheAddr node_addr = node->address().value(); 769 CacheAddr node_addr = node->address().value();
748 if (prev->Data()->next == node_addr && 770 if (prev->Data()->next == node_addr && next->Data()->prev == node_addr) {
749 next->Data()->prev == node_addr) {
750 // A regular linked node. 771 // A regular linked node.
751 return true; 772 return true;
752 } 773 }
753 774
754 Trace("CheckLinks 0x%x (0x%x 0x%x)", node_addr, 775 Trace("CheckLinks 0x%x (0x%x 0x%x)",
755 prev->Data()->next, next->Data()->prev); 776 node_addr,
777 prev->Data()->next,
778 next->Data()->prev);
756 779
757 if (node_addr != prev->address().value() && 780 if (node_addr != prev->address().value() &&
758 node_addr != next->address().value() && 781 node_addr != next->address().value() &&
759 prev->Data()->next == next->address().value() && 782 prev->Data()->next == next->address().value() &&
760 next->Data()->prev == prev->address().value()) { 783 next->Data()->prev == prev->address().value()) {
761 // The list is actually ok, node is wrong. 784 // The list is actually ok, node is wrong.
762 Trace("node 0x%x out of list %d", node_addr, list); 785 Trace("node 0x%x out of list %d", node_addr, list);
763 node->Data()->next = 0; 786 node->Data()->next = 0;
764 node->Data()->prev = 0; 787 node->Data()->prev = 0;
765 node->Store(); 788 node->Store();
766 return false; 789 return false;
767 } 790 }
768 791
769 if (prev->Data()->next == node_addr || 792 if (prev->Data()->next == node_addr || next->Data()->prev == node_addr) {
770 next->Data()->prev == node_addr) {
771 // Only one link is weird, lets double check. 793 // Only one link is weird, lets double check.
772 if (prev->Data()->next != node_addr && IsHead(node_addr, list)) 794 if (prev->Data()->next != node_addr && IsHead(node_addr, list))
773 return true; 795 return true;
774 796
775 if (next->Data()->prev != node_addr && IsTail(node_addr, list)) 797 if (next->Data()->prev != node_addr && IsTail(node_addr, list))
776 return true; 798 return true;
777 } 799 }
778 800
779 LOG(ERROR) << "Inconsistent LRU."; 801 LOG(ERROR) << "Inconsistent LRU.";
780 STRESS_NOTREACHED(); 802 STRESS_NOTREACHED();
(...skipping 11 matching lines...) Expand all
792 backend_->CriticalError(ERR_INVALID_LINKS); 814 backend_->CriticalError(ERR_INVALID_LINKS);
793 return false; 815 return false;
794 } 816 }
795 817
796 return true; 818 return true;
797 } 819 }
798 820
799 int Rankings::CheckList(List list) { 821 int Rankings::CheckList(List list) {
800 Addr last1, last2; 822 Addr last1, last2;
801 int head_items; 823 int head_items;
802 int rv = CheckListSection(list, last1, last2, true, // Head to tail. 824 int rv = CheckListSection(list,
803 &last1, &last2, &head_items); 825 last1,
826 last2,
827 true, // Head to tail.
828 &last1,
829 &last2,
830 &head_items);
804 if (rv == ERR_NO_ERROR) 831 if (rv == ERR_NO_ERROR)
805 return head_items; 832 return head_items;
806 833
807 return rv; 834 return rv;
808 } 835 }
809 836
810 // Note that the returned error codes assume a forward walk (from head to tail) 837 // Note that the returned error codes assume a forward walk (from head to tail)
811 // so they have to be adjusted accordingly by the caller. We use two stop values 838 // so they have to be adjusted accordingly by the caller. We use two stop values
812 // to be able to detect a corrupt node at the end that is not linked going back. 839 // to be able to detect a corrupt node at the end that is not linked going back.
813 int Rankings::CheckListSection(List list, Addr end1, Addr end2, bool forward, 840 int Rankings::CheckListSection(List list,
814 Addr* last, Addr* second_last, int* num_items) { 841 Addr end1,
842 Addr end2,
843 bool forward,
844 Addr* last,
845 Addr* second_last,
846 int* num_items) {
815 Addr current = forward ? heads_[list] : tails_[list]; 847 Addr current = forward ? heads_[list] : tails_[list];
816 *last = *second_last = current; 848 *last = *second_last = current;
817 *num_items = 0; 849 *num_items = 0;
818 if (!current.is_initialized()) 850 if (!current.is_initialized())
819 return ERR_NO_ERROR; 851 return ERR_NO_ERROR;
820 852
821 if (!current.SanityCheckForRankings()) 853 if (!current.SanityCheckForRankings())
822 return ERR_INVALID_HEAD; 854 return ERR_INVALID_HEAD;
823 855
824 scoped_ptr<CacheRankingsBlock> node; 856 scoped_ptr<CacheRankingsBlock> node;
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 void Rankings::DecrementCounter(List list) { 948 void Rankings::DecrementCounter(List list) {
917 if (!count_lists_) 949 if (!count_lists_)
918 return; 950 return;
919 951
920 DCHECK(control_data_->sizes[list] > 0); 952 DCHECK(control_data_->sizes[list] > 0);
921 if (control_data_->sizes[list] > 0) 953 if (control_data_->sizes[list] > 0)
922 control_data_->sizes[list]--; 954 control_data_->sizes[list]--;
923 } 955 }
924 956
925 } // namespace disk_cache 957 } // namespace disk_cache
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698