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_BLOCK_FILES_H_
8#define NET_DISK_CACHE_BLOCKFILE_BLOCK_FILES_H_
9
10#include <vector>
11
12#include "base/files/file_path.h"
13#include "base/gtest_prod_util.h"
14#include "base/memory/scoped_ptr.h"
15#include "net/base/net_export.h"
16#include "net/disk_cache/blockfile/addr.h"
17#include "net/disk_cache/blockfile/disk_format_base.h"
18#include "net/disk_cache/blockfile/mapped_file.h"
19
20namespace base {
21class ThreadChecker;
22}
23
24namespace disk_cache {
25
26// An instance of this class represents the header of a block file in memory.
27// Note that this class doesn't perform any file operation (as in it only deals
28// with entities in memory).
29// The header of a block file (and hence, this object) is all that is needed to
30// perform common operations like allocating or releasing space for storage;
31// actual access to that storage, however, is not performed through this class.
32class NET_EXPORT_PRIVATE BlockHeader {
33 public:
34  BlockHeader();
35  explicit BlockHeader(BlockFileHeader* header);
36  explicit BlockHeader(MappedFile* file);
37  BlockHeader(const BlockHeader& other);
38  ~BlockHeader();
39
40  // Creates a new entry of |size| blocks on the allocation map, updating the
41  // apropriate counters.
42  bool CreateMapBlock(int size, int* index);
43
44  // Deletes the block pointed by |index|.
45  void DeleteMapBlock(int index, int block_size);
46
47  // Returns true if the specified block is used.
48  bool UsedMapBlock(int index, int size);
49
50  // Restores the "empty counters" and allocation hints.
51  void FixAllocationCounters();
52
53  // Returns true if the current block file should not be used as-is to store
54  // more records. |block_count| is the number of blocks to allocate.
55  bool NeedToGrowBlockFile(int block_count) const;
56
57  // Returns true if this block file can be used to store an extra record of
58  // size |block_count|.
59  bool CanAllocate(int block_count) const;
60
61  // Returns the number of empty blocks for this file.
62  int EmptyBlocks() const;
63
64  // Returns the minumum number of allocations that can be satisfied.
65  int MinimumAllocations() const;
66
67  // Returns the number of blocks that this file can store.
68  int Capacity() const;
69
70  // Returns true if the counters look OK.
71  bool ValidateCounters() const;
72
73  // Returns the identifiers of this and the next file (0 if there is none).
74  int FileId() const;
75  int NextFileId() const;
76
77  // Returns the size of the wrapped structure (BlockFileHeader).
78  int Size() const;
79
80  // Returns a pointer to the underlying BlockFileHeader.
81  // TODO(rvargas): This may be removed with the support for V2.
82  BlockFileHeader* Header();
83
84 private:
85  BlockFileHeader* header_;
86};
87
88typedef std::vector<BlockHeader> BlockFilesBitmaps;
89
90// This class handles the set of block-files open by the disk cache.
91class NET_EXPORT_PRIVATE BlockFiles {
92 public:
93  explicit BlockFiles(const base::FilePath& path);
94  ~BlockFiles();
95
96  // Performs the object initialization. create_files indicates if the backing
97  // files should be created or just open.
98  bool Init(bool create_files);
99
100  // Returns the file that stores a given address.
101  MappedFile* GetFile(Addr address);
102
103  // Creates a new entry on a block file. block_type indicates the size of block
104  // to be used (as defined on cache_addr.h), block_count is the number of
105  // blocks to allocate, and block_address is the address of the new entry.
106  bool CreateBlock(FileType block_type, int block_count, Addr* block_address);
107
108  // Removes an entry from the block files. If deep is true, the storage is zero
109  // filled; otherwise the entry is removed but the data is not altered (must be
110  // already zeroed).
111  void DeleteBlock(Addr address, bool deep);
112
113  // Close all the files and set the internal state to be initializad again. The
114  // cache is being purged.
115  void CloseFiles();
116
117  // Sends UMA stats.
118  void ReportStats();
119
120  // Returns true if the blocks pointed by a given address are currently used.
121  // This method is only intended for debugging.
122  bool IsValid(Addr address);
123
124 private:
125  // Set force to true to overwrite the file if it exists.
126  bool CreateBlockFile(int index, FileType file_type, bool force);
127  bool OpenBlockFile(int index);
128
129  // Attemp to grow this file. Fails if the file cannot be extended anymore.
130  bool GrowBlockFile(MappedFile* file, BlockFileHeader* header);
131
132  // Returns the appropriate file to use for a new block.
133  MappedFile* FileForNewBlock(FileType block_type, int block_count);
134
135  // Returns the next block file on this chain, creating new files if needed.
136  MappedFile* NextFile(MappedFile* file);
137
138  // Creates an empty block file and returns its index.
139  int CreateNextBlockFile(FileType block_type);
140
141  // Removes a chained block file that is now empty.
142  bool RemoveEmptyFile(FileType block_type);
143
144  // Restores the header of a potentially inconsistent file.
145  bool FixBlockFileHeader(MappedFile* file);
146
147  // Retrieves stats for the given file index.
148  void GetFileStats(int index, int* used_count, int* load);
149
150  // Returns the filename for a given file index.
151  base::FilePath Name(int index);
152
153  bool init_;
154  char* zero_buffer_;  // Buffer to speed-up cleaning deleted entries.
155  base::FilePath path_;  // Path to the backing folder.
156  std::vector<MappedFile*> block_files_;  // The actual files.
157  scoped_ptr<base::ThreadChecker> thread_checker_;
158
159  FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_ZeroSizeFile);
160  FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_TruncatedFile);
161  FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_InvalidFile);
162  FRIEND_TEST_ALL_PREFIXES(DiskCacheTest, BlockFiles_Stats);
163
164  DISALLOW_COPY_AND_ASSIGN(BlockFiles);
165};
166
167}  // namespace disk_cache
168
169#endif  // NET_DISK_CACHE_BLOCKFILE_BLOCK_FILES_H_
170