summaryrefslogtreecommitdiffstats
path: root/chromium/net/disk_cache/blockfile/rankings.h
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/net/disk_cache/blockfile/rankings.h')
-rw-r--r--chromium/net/disk_cache/blockfile/rankings.h214
1 files changed, 214 insertions, 0 deletions
diff --git a/chromium/net/disk_cache/blockfile/rankings.h b/chromium/net/disk_cache/blockfile/rankings.h
new file mode 100644
index 00000000000..4224d0058eb
--- /dev/null
+++ b/chromium/net/disk_cache/blockfile/rankings.h
@@ -0,0 +1,214 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// See net/disk_cache/disk_cache.h for the public interface.
+
+#ifndef NET_DISK_CACHE_BLOCKFILE_RANKINGS_H_
+#define NET_DISK_CACHE_BLOCKFILE_RANKINGS_H_
+
+#include <list>
+
+#include "base/memory/scoped_ptr.h"
+#include "net/disk_cache/blockfile/addr.h"
+#include "net/disk_cache/blockfile/mapped_file.h"
+#include "net/disk_cache/blockfile/storage_block.h"
+
+namespace disk_cache {
+
+class BackendImpl;
+struct LruData;
+struct RankingsNode;
+typedef StorageBlock<RankingsNode> CacheRankingsBlock;
+
+// Type of crashes generated for the unit tests.
+enum RankCrashes {
+ NO_CRASH = 0,
+ INSERT_EMPTY_1,
+ INSERT_EMPTY_2,
+ INSERT_EMPTY_3,
+ INSERT_ONE_1,
+ INSERT_ONE_2,
+ INSERT_ONE_3,
+ INSERT_LOAD_1,
+ INSERT_LOAD_2,
+ REMOVE_ONE_1,
+ REMOVE_ONE_2,
+ REMOVE_ONE_3,
+ REMOVE_ONE_4,
+ REMOVE_HEAD_1,
+ REMOVE_HEAD_2,
+ REMOVE_HEAD_3,
+ REMOVE_HEAD_4,
+ REMOVE_TAIL_1,
+ REMOVE_TAIL_2,
+ REMOVE_TAIL_3,
+ REMOVE_LOAD_1,
+ REMOVE_LOAD_2,
+ REMOVE_LOAD_3,
+ MAX_CRASH
+};
+
+// This class handles the ranking information for the cache.
+class Rankings {
+ public:
+ // Possible lists of entries.
+ enum List {
+ NO_USE = 0, // List of entries that have not been reused.
+ LOW_USE, // List of entries with low reuse.
+ HIGH_USE, // List of entries with high reuse.
+ RESERVED, // Reserved for future use.
+ DELETED, // List of recently deleted or doomed entries.
+ LAST_ELEMENT
+ };
+
+ // This class provides a specialized version of scoped_ptr, that calls
+ // Rankings whenever a CacheRankingsBlock is deleted, to keep track of cache
+ // iterators that may go stale.
+ class ScopedRankingsBlock : public scoped_ptr<CacheRankingsBlock> {
+ public:
+ ScopedRankingsBlock();
+ explicit ScopedRankingsBlock(Rankings* rankings);
+ ScopedRankingsBlock(Rankings* rankings, CacheRankingsBlock* node);
+
+ ~ScopedRankingsBlock() {
+ rankings_->FreeRankingsBlock(get());
+ }
+
+ void set_rankings(Rankings* rankings) {
+ rankings_ = rankings;
+ }
+
+ // scoped_ptr::reset will delete the object.
+ void reset(CacheRankingsBlock* p = NULL) {
+ if (p != get())
+ rankings_->FreeRankingsBlock(get());
+ scoped_ptr<CacheRankingsBlock>::reset(p);
+ }
+
+ private:
+ Rankings* rankings_;
+ DISALLOW_COPY_AND_ASSIGN(ScopedRankingsBlock);
+ };
+
+ // If we have multiple lists, we have to iterate through all at the same time.
+ // This structure keeps track of where we are on the iteration.
+ struct Iterator {
+ explicit Iterator(Rankings* rankings);
+ ~Iterator();
+
+ List list; // Which entry was returned to the user.
+ CacheRankingsBlock* nodes[3]; // Nodes on the first three lists.
+ Rankings* my_rankings;
+ };
+
+ Rankings();
+ ~Rankings();
+
+ bool Init(BackendImpl* backend, bool count_lists);
+
+ // Restores original state, leaving the object ready for initialization.
+ void Reset();
+
+ // Inserts a given entry at the head of the queue.
+ void Insert(CacheRankingsBlock* node, bool modified, List list);
+
+ // Removes a given entry from the LRU list. If |strict| is true, this method
+ // assumes that |node| is not pointed to by an active iterator. On the other
+ // hand, removing that restriction allows the current "head" of an iterator
+ // to be removed from the list (basically without control of the code that is
+ // performing the iteration), so it should be used with extra care.
+ void Remove(CacheRankingsBlock* node, List list, bool strict);
+
+ // Moves a given entry to the head.
+ void UpdateRank(CacheRankingsBlock* node, bool modified, List list);
+
+ // Iterates through the list.
+ CacheRankingsBlock* GetNext(CacheRankingsBlock* node, List list);
+ CacheRankingsBlock* GetPrev(CacheRankingsBlock* node, List list);
+ void FreeRankingsBlock(CacheRankingsBlock* node);
+
+ // Controls tracking of nodes used for enumerations.
+ void TrackRankingsBlock(CacheRankingsBlock* node, bool start_tracking);
+
+ // Peforms a simple self-check of the lists, and returns the number of items
+ // or an error code (negative value).
+ int SelfCheck();
+
+ // Returns false if the entry is clearly invalid. from_list is true if the
+ // node comes from the LRU list.
+ bool SanityCheck(CacheRankingsBlock* node, bool from_list) const;
+ bool DataSanityCheck(CacheRankingsBlock* node, bool from_list) const;
+
+ // Sets the |contents| field of |node| to |address|.
+ void SetContents(CacheRankingsBlock* node, CacheAddr address);
+
+ private:
+ typedef std::pair<CacheAddr, CacheRankingsBlock*> IteratorPair;
+ typedef std::list<IteratorPair> IteratorList;
+
+ void ReadHeads();
+ void ReadTails();
+ void WriteHead(List list);
+ void WriteTail(List list);
+
+ // Gets the rankings information for a given rankings node. We may end up
+ // sharing the actual memory with a loaded entry, but we are not taking a
+ // reference to that entry, so |rankings| must be short lived.
+ bool GetRanking(CacheRankingsBlock* rankings);
+
+ // Makes |rankings| suitable to live a long life.
+ void ConvertToLongLived(CacheRankingsBlock* rankings);
+
+ // Finishes a list modification after a crash.
+ void CompleteTransaction();
+ void FinishInsert(CacheRankingsBlock* rankings);
+ void RevertRemove(CacheRankingsBlock* rankings);
+
+ // Returns false if node is not properly linked. This method may change the
+ // provided |list| to reflect the list where this node is actually stored.
+ bool CheckLinks(CacheRankingsBlock* node, CacheRankingsBlock* prev,
+ CacheRankingsBlock* next, List* list);
+
+ // Checks the links between two consecutive nodes.
+ bool CheckSingleLink(CacheRankingsBlock* prev, CacheRankingsBlock* next);
+
+ // Peforms a simple check of the list, and returns the number of items or an
+ // error code (negative value).
+ int CheckList(List list);
+
+ // Walks a list in the desired direction until the nodes |end1| or |end2| are
+ // reached. Returns an error code (0 on success), the number of items verified
+ // and the addresses of the last nodes visited.
+ int CheckListSection(List list, Addr end1, Addr end2, bool forward,
+ Addr* last, Addr* second_last, int* num_items);
+
+ // Returns true if addr is the head or tail of any list. When there is a
+ // match |list| will contain the list number for |addr|.
+ bool IsHead(CacheAddr addr, List* list) const;
+ bool IsTail(CacheAddr addr, List* list) const;
+
+ // Updates the iterators whenever node is being changed.
+ void UpdateIterators(CacheRankingsBlock* node);
+
+ // Invalidates the iterators pointing to this node.
+ void InvalidateIterators(CacheRankingsBlock* node);
+
+ // Keeps track of the number of entries on a list.
+ void IncrementCounter(List list);
+ void DecrementCounter(List list);
+
+ bool init_;
+ bool count_lists_;
+ Addr heads_[LAST_ELEMENT];
+ Addr tails_[LAST_ELEMENT];
+ BackendImpl* backend_;
+ LruData* control_data_; // Data related to the LRU lists.
+ IteratorList iterators_;
+
+ DISALLOW_COPY_AND_ASSIGN(Rankings);
+};
+
+} // namespace disk_cache
+
+#endif // NET_DISK_CACHE_BLOCKFILE_RANKINGS_H_