| OLD | NEW |
| (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 // See net/disk_cache/disk_cache.h for the public interface. | |
| 6 | |
| 7 #ifndef NET_DISK_CACHE_BLOCKFILE_RANKINGS_H_ | |
| 8 #define NET_DISK_CACHE_BLOCKFILE_RANKINGS_H_ | |
| 9 | |
| 10 #include <list> | |
| 11 | |
| 12 #include "base/memory/scoped_ptr.h" | |
| 13 #include "net/disk_cache/blockfile/addr.h" | |
| 14 #include "net/disk_cache/blockfile/mapped_file.h" | |
| 15 #include "net/disk_cache/blockfile/storage_block.h" | |
| 16 | |
| 17 namespace disk_cache { | |
| 18 | |
| 19 class BackendImpl; | |
| 20 struct LruData; | |
| 21 struct RankingsNode; | |
| 22 typedef StorageBlock<RankingsNode> CacheRankingsBlock; | |
| 23 | |
| 24 // Type of crashes generated for the unit tests. | |
| 25 enum RankCrashes { | |
| 26 NO_CRASH = 0, | |
| 27 INSERT_EMPTY_1, | |
| 28 INSERT_EMPTY_2, | |
| 29 INSERT_EMPTY_3, | |
| 30 INSERT_ONE_1, | |
| 31 INSERT_ONE_2, | |
| 32 INSERT_ONE_3, | |
| 33 INSERT_LOAD_1, | |
| 34 INSERT_LOAD_2, | |
| 35 REMOVE_ONE_1, | |
| 36 REMOVE_ONE_2, | |
| 37 REMOVE_ONE_3, | |
| 38 REMOVE_ONE_4, | |
| 39 REMOVE_HEAD_1, | |
| 40 REMOVE_HEAD_2, | |
| 41 REMOVE_HEAD_3, | |
| 42 REMOVE_HEAD_4, | |
| 43 REMOVE_TAIL_1, | |
| 44 REMOVE_TAIL_2, | |
| 45 REMOVE_TAIL_3, | |
| 46 REMOVE_LOAD_1, | |
| 47 REMOVE_LOAD_2, | |
| 48 REMOVE_LOAD_3, | |
| 49 MAX_CRASH | |
| 50 }; | |
| 51 | |
| 52 // This class handles the ranking information for the cache. | |
| 53 class Rankings { | |
| 54 public: | |
| 55 // Possible lists of entries. | |
| 56 enum List { | |
| 57 NO_USE = 0, // List of entries that have not been reused. | |
| 58 LOW_USE, // List of entries with low reuse. | |
| 59 HIGH_USE, // List of entries with high reuse. | |
| 60 RESERVED, // Reserved for future use. | |
| 61 DELETED, // List of recently deleted or doomed entries. | |
| 62 LAST_ELEMENT | |
| 63 }; | |
| 64 | |
| 65 // This class provides a specialized version of scoped_ptr, that calls | |
| 66 // Rankings whenever a CacheRankingsBlock is deleted, to keep track of cache | |
| 67 // iterators that may go stale. | |
| 68 class ScopedRankingsBlock : public scoped_ptr<CacheRankingsBlock> { | |
| 69 public: | |
| 70 ScopedRankingsBlock(); | |
| 71 explicit ScopedRankingsBlock(Rankings* rankings); | |
| 72 ScopedRankingsBlock(Rankings* rankings, CacheRankingsBlock* node); | |
| 73 | |
| 74 ~ScopedRankingsBlock() { | |
| 75 rankings_->FreeRankingsBlock(get()); | |
| 76 } | |
| 77 | |
| 78 void set_rankings(Rankings* rankings) { | |
| 79 rankings_ = rankings; | |
| 80 } | |
| 81 | |
| 82 // scoped_ptr::reset will delete the object. | |
| 83 void reset(CacheRankingsBlock* p = NULL) { | |
| 84 if (p != get()) | |
| 85 rankings_->FreeRankingsBlock(get()); | |
| 86 scoped_ptr<CacheRankingsBlock>::reset(p); | |
| 87 } | |
| 88 | |
| 89 private: | |
| 90 Rankings* rankings_; | |
| 91 DISALLOW_COPY_AND_ASSIGN(ScopedRankingsBlock); | |
| 92 }; | |
| 93 | |
| 94 // If we have multiple lists, we have to iterate through all at the same time. | |
| 95 // This structure keeps track of where we are on the iteration. | |
| 96 struct Iterator { | |
| 97 Iterator(); | |
| 98 void Reset(); | |
| 99 | |
| 100 List list; // Which entry was returned to the user. | |
| 101 CacheRankingsBlock* nodes[3]; // Nodes on the first three lists. | |
| 102 Rankings* my_rankings; | |
| 103 }; | |
| 104 | |
| 105 Rankings(); | |
| 106 ~Rankings(); | |
| 107 | |
| 108 bool Init(BackendImpl* backend, bool count_lists); | |
| 109 | |
| 110 // Restores original state, leaving the object ready for initialization. | |
| 111 void Reset(); | |
| 112 | |
| 113 // Inserts a given entry at the head of the queue. | |
| 114 void Insert(CacheRankingsBlock* node, bool modified, List list); | |
| 115 | |
| 116 // Removes a given entry from the LRU list. If |strict| is true, this method | |
| 117 // assumes that |node| is not pointed to by an active iterator. On the other | |
| 118 // hand, removing that restriction allows the current "head" of an iterator | |
| 119 // to be removed from the list (basically without control of the code that is | |
| 120 // performing the iteration), so it should be used with extra care. | |
| 121 void Remove(CacheRankingsBlock* node, List list, bool strict); | |
| 122 | |
| 123 // Moves a given entry to the head. | |
| 124 void UpdateRank(CacheRankingsBlock* node, bool modified, List list); | |
| 125 | |
| 126 // Iterates through the list. | |
| 127 CacheRankingsBlock* GetNext(CacheRankingsBlock* node, List list); | |
| 128 CacheRankingsBlock* GetPrev(CacheRankingsBlock* node, List list); | |
| 129 void FreeRankingsBlock(CacheRankingsBlock* node); | |
| 130 | |
| 131 // Controls tracking of nodes used for enumerations. | |
| 132 void TrackRankingsBlock(CacheRankingsBlock* node, bool start_tracking); | |
| 133 | |
| 134 // Peforms a simple self-check of the lists, and returns the number of items | |
| 135 // or an error code (negative value). | |
| 136 int SelfCheck(); | |
| 137 | |
| 138 // Returns false if the entry is clearly invalid. from_list is true if the | |
| 139 // node comes from the LRU list. | |
| 140 bool SanityCheck(CacheRankingsBlock* node, bool from_list) const; | |
| 141 bool DataSanityCheck(CacheRankingsBlock* node, bool from_list) const; | |
| 142 | |
| 143 // Sets the |contents| field of |node| to |address|. | |
| 144 void SetContents(CacheRankingsBlock* node, CacheAddr address); | |
| 145 | |
| 146 private: | |
| 147 typedef std::pair<CacheAddr, CacheRankingsBlock*> IteratorPair; | |
| 148 typedef std::list<IteratorPair> IteratorList; | |
| 149 | |
| 150 void ReadHeads(); | |
| 151 void ReadTails(); | |
| 152 void WriteHead(List list); | |
| 153 void WriteTail(List list); | |
| 154 | |
| 155 // Gets the rankings information for a given rankings node. We may end up | |
| 156 // sharing the actual memory with a loaded entry, but we are not taking a | |
| 157 // reference to that entry, so |rankings| must be short lived. | |
| 158 bool GetRanking(CacheRankingsBlock* rankings); | |
| 159 | |
| 160 // Makes |rankings| suitable to live a long life. | |
| 161 void ConvertToLongLived(CacheRankingsBlock* rankings); | |
| 162 | |
| 163 // Finishes a list modification after a crash. | |
| 164 void CompleteTransaction(); | |
| 165 void FinishInsert(CacheRankingsBlock* rankings); | |
| 166 void RevertRemove(CacheRankingsBlock* rankings); | |
| 167 | |
| 168 // Returns false if node is not properly linked. This method may change the | |
| 169 // provided |list| to reflect the list where this node is actually stored. | |
| 170 bool CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev, | |
| 171 CacheRankingsBlock* next, List* list); | |
| 172 | |
| 173 // Checks the links between two consecutive nodes. | |
| 174 bool CheckSingleLink(CacheRankingsBlock* prev, CacheRankingsBlock* next); | |
| 175 | |
| 176 // Peforms a simple check of the list, and returns the number of items or an | |
| 177 // error code (negative value). | |
| 178 int CheckList(List list); | |
| 179 | |
| 180 // Walks a list in the desired direction until the nodes |end1| or |end2| are | |
| 181 // reached. Returns an error code (0 on success), the number of items verified | |
| 182 // and the addresses of the last nodes visited. | |
| 183 int CheckListSection(List list, Addr end1, Addr end2, bool forward, | |
| 184 Addr* last, Addr* second_last, int* num_items); | |
| 185 | |
| 186 // Returns true if addr is the head or tail of any list. When there is a | |
| 187 // match |list| will contain the list number for |addr|. | |
| 188 bool IsHead(CacheAddr addr, List* list) const; | |
| 189 bool IsTail(CacheAddr addr, List* list) const; | |
| 190 | |
| 191 // Updates the iterators whenever node is being changed. | |
| 192 void UpdateIterators(CacheRankingsBlock* node); | |
| 193 | |
| 194 // Invalidates the iterators pointing to this node. | |
| 195 void InvalidateIterators(CacheRankingsBlock* node); | |
| 196 | |
| 197 // Keeps track of the number of entries on a list. | |
| 198 void IncrementCounter(List list); | |
| 199 void DecrementCounter(List list); | |
| 200 | |
| 201 bool init_; | |
| 202 bool count_lists_; | |
| 203 Addr heads_[LAST_ELEMENT]; | |
| 204 Addr tails_[LAST_ELEMENT]; | |
| 205 BackendImpl* backend_; | |
| 206 LruData* control_data_; // Data related to the LRU lists. | |
| 207 IteratorList iterators_; | |
| 208 | |
| 209 DISALLOW_COPY_AND_ASSIGN(Rankings); | |
| 210 }; | |
| 211 | |
| 212 } // namespace disk_cache | |
| 213 | |
| 214 #endif // NET_DISK_CACHE_BLOCKFILE_RANKINGS_H_ | |
| OLD | NEW |