15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See net/disk_cache/disk_cache.h for the public interface. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef NET_DISK_CACHE_BLOCK_FILES_H_ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NET_DISK_CACHE_BLOCK_FILES_H_ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/addr.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/disk_cache/disk_format_base.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/disk_cache/mapped_file.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ThreadChecker; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// An instance of this class represents the header of a block file in memory. 27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Note that this class doesn't perform any file operation (as in it only deals 28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// with entities in memory). 29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// The header of a block file (and hence, this object) is all that is needed to 30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// perform common operations like allocating or releasing space for storage; 31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// actual access to that storage, however, is not performed through this class. 32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass NET_EXPORT_PRIVATE BlockHeader { 33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public: 34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BlockHeader(); 35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit BlockHeader(BlockFileHeader* header); 36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch explicit BlockHeader(MappedFile* file); 37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BlockHeader(const BlockHeader& other); 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ~BlockHeader(); 39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Creates a new entry of |size| blocks on the allocation map, updating the 41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // apropriate counters. 42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool CreateMapBlock(int size, int* index); 43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Deletes the block pointed by |index|. 45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void DeleteMapBlock(int index, int block_size); 46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns true if the specified block is used. 48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool UsedMapBlock(int index, int size); 49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Restores the "empty counters" and allocation hints. 51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void FixAllocationCounters(); 52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns true if the current block file should not be used as-is to store 54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // more records. |block_count| is the number of blocks to allocate. 55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool NeedToGrowBlockFile(int block_count) const; 56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Returns true if this block file can be used to store an extra record of 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // size |block_count|. 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) bool CanAllocate(int block_count) const; 60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns the number of empty blocks for this file. 62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int EmptyBlocks() const; 63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Returns the minumum number of allocations that can be satisfied. 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int MinimumAllocations() const; 66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Returns the number of blocks that this file can store. 68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int Capacity() const; 69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns true if the counters look OK. 71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch bool ValidateCounters() const; 72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Returns the identifiers of this and the next file (0 if there is none). 74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int FileId() const; 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) int NextFileId() const; 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns the size of the wrapped structure (BlockFileHeader). 78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int Size() const; 79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // Returns a pointer to the underlying BlockFileHeader. 81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(rvargas): This may be removed with the support for V2. 82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) BlockFileHeader* Header(); 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch private: 85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch BlockFileHeader* header_; 86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}; 87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochtypedef std::vector<BlockHeader> BlockFilesBitmaps; 89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class handles the set of block-files open by the disk cache. 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE BlockFiles { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit BlockFiles(const base::FilePath& path); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~BlockFiles(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Performs the object initialization. create_files indicates if the backing 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // files should be created or just open. 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Init(bool create_files); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the file that stores a given address. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MappedFile* GetFile(Addr address); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates a new entry on a block file. block_type indicates the size of block 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to be used (as defined on cache_addr.h), block_count is the number of 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // blocks to allocate, and block_address is the address of the new entry. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CreateBlock(FileType block_type, int block_count, Addr* block_address); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes an entry from the block files. If deep is true, the storage is zero 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // filled; otherwise the entry is removed but the data is not altered (must be 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // already zeroed). 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteBlock(Addr address, bool deep); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close all the files and set the internal state to be initializad again. The 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // cache is being purged. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CloseFiles(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends UMA stats. 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReportStats(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns true if the blocks pointed by a given address are currently used. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This method is only intended for debugging. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsValid(Addr address); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set force to true to overwrite the file if it exists. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool CreateBlockFile(int index, FileType file_type, bool force); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool OpenBlockFile(int index); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attemp to grow this file. Fails if the file cannot be extended anymore. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GrowBlockFile(MappedFile* file, BlockFileHeader* header); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the appropriate file to use for a new block. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MappedFile* FileForNewBlock(FileType block_type, int block_count); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the next block file on this chain, creating new files if needed. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MappedFile* NextFile(MappedFile* file); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates an empty block file and returns its index. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int CreateNextBlockFile(FileType block_type); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Removes a chained block file that is now empty. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RemoveEmptyFile(FileType block_type); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Restores the header of a potentially inconsistent file. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool FixBlockFileHeader(MappedFile* file); 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieves stats for the given file index. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void GetFileStats(int index, int* used_count, int* load); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the filename for a given file index. 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath Name(int index); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool init_; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* zero_buffer_; // Buffer to speed-up cleaning deleted entries. 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path_; // Path to the backing folder. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<MappedFile*> block_files_; // The actual files. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<base::ThreadChecker> thread_checker_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_ZeroSizeFile); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_TruncatedFile); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_InvalidFile); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_Stats); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BlockFiles); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace disk_cache 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // NET_DISK_CACHE_BLOCK_FILES_H_ 170