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 // This is an internal class that handles the address of a cache record. 6 // See net/disk_cache/disk_cache.h for the public interface of the cache. 7 8 #ifndef NET_DISK_CACHE_BLOCKFILE_ADDR_H_ 9 #define NET_DISK_CACHE_BLOCKFILE_ADDR_H_ 10 11 #include "net/base/net_export.h" 12 #include "net/disk_cache/blockfile/disk_format_base.h" 13 14 namespace disk_cache { 15 16 enum FileType { 17 EXTERNAL = 0, 18 RANKINGS = 1, 19 BLOCK_256 = 2, 20 BLOCK_1K = 3, 21 BLOCK_4K = 4, 22 BLOCK_FILES = 5, 23 BLOCK_ENTRIES = 6, 24 BLOCK_EVICTED = 7 25 }; 26 27 const int kMaxBlockSize = 4096 * 4; 28 const int kMaxBlockFile = 255; 29 const int kMaxNumBlocks = 4; 30 const int kFirstAdditionalBlockFile = 4; 31 const int kFirstAdditionalBlockFileV3 = 7; 32 33 // Defines a storage address for a cache record 34 // 35 // Header: 36 // 1000 0000 0000 0000 0000 0000 0000 0000 : initialized bit 37 // 0111 0000 0000 0000 0000 0000 0000 0000 : file type 38 // 39 // File type values: 40 // 0 = separate file on disk 41 // 1 = rankings block file 42 // 2 = 256 byte block file 43 // 3 = 1k byte block file 44 // 4 = 4k byte block file 45 // 5 = external files block file 46 // 6 = active entries block file 47 // 7 = evicted entries block file 48 // 49 // If separate file: 50 // 0000 1111 1111 1111 1111 1111 1111 1111 : file# 0 - 268,435,456 (2^28) 51 // 52 // If block file: 53 // 0000 1100 0000 0000 0000 0000 0000 0000 : reserved bits 54 // 0000 0011 0000 0000 0000 0000 0000 0000 : number of contiguous blocks 1-4 55 // 0000 0000 1111 1111 0000 0000 0000 0000 : file selector 0 - 255 56 // 0000 0000 0000 0000 1111 1111 1111 1111 : block# 0 - 65,535 (2^16) 57 // 58 // Note that an Addr can be used to "point" to a variety of different objects, 59 // from a given type of entry to random blobs of data. Conceptually, an Addr is 60 // just a number that someone can inspect to find out how to locate the desired 61 // record. Most users will not care about the specific bits inside Addr, for 62 // example, what parts of it point to a file number; only the code that has to 63 // select a specific file would care about those specific bits. 64 // 65 // From a general point of view, an Addr has a total capacity of 2^24 entities, 66 // in that it has 24 bits that can identify individual records. Note that the 67 // address space is bigger for independent files (2^28), but that would not be 68 // the general case. 69 class NET_EXPORT_PRIVATE Addr { 70 public: 71 Addr() : value_(0) {} 72 explicit Addr(CacheAddr address) : value_(address) {} 73 Addr(FileType file_type, int max_blocks, int block_file, int index) { 74 value_ = ((file_type << kFileTypeOffset) & kFileTypeMask) | 75 (((max_blocks - 1) << kNumBlocksOffset) & kNumBlocksMask) | 76 ((block_file << kFileSelectorOffset) & kFileSelectorMask) | 77 (index & kStartBlockMask) | kInitializedMask; 78 } 79 80 CacheAddr value() const { return value_; } 81 void set_value(CacheAddr address) { 82 value_ = address; 83 } 84 85 bool is_initialized() const { 86 return (value_ & kInitializedMask) != 0; 87 } 88 89 bool is_separate_file() const { 90 return (value_ & kFileTypeMask) == 0; 91 } 92 93 bool is_block_file() const { 94 return !is_separate_file(); 95 } 96 97 FileType file_type() const { 98 return static_cast<FileType>((value_ & kFileTypeMask) >> kFileTypeOffset); 99 } 100 101 int FileNumber() const { 102 if (is_separate_file()) 103 return value_ & kFileNameMask; 104 else 105 return ((value_ & kFileSelectorMask) >> kFileSelectorOffset); 106 } 107 108 int start_block() const; 109 int num_blocks() const; 110 bool SetFileNumber(int file_number); 111 int BlockSize() const { 112 return BlockSizeForFileType(file_type()); 113 } 114 115 bool operator==(Addr other) const { 116 return value_ == other.value_; 117 } 118 119 bool operator!=(Addr other) const { 120 return value_ != other.value_; 121 } 122 123 static int BlockSizeForFileType(FileType file_type) { 124 switch (file_type) { 125 case RANKINGS: 126 return 36; 127 case BLOCK_256: 128 return 256; 129 case BLOCK_1K: 130 return 1024; 131 case BLOCK_4K: 132 return 4096; 133 case BLOCK_FILES: 134 return 8; 135 case BLOCK_ENTRIES: 136 return 104; 137 case BLOCK_EVICTED: 138 return 48; 139 default: 140 return 0; 141 } 142 } 143 144 static FileType RequiredFileType(int size) { 145 if (size < 1024) 146 return BLOCK_256; 147 else if (size < 4096) 148 return BLOCK_1K; 149 else if (size <= 4096 * 4) 150 return BLOCK_4K; 151 else 152 return EXTERNAL; 153 } 154 155 static int RequiredBlocks(int size, FileType file_type) { 156 int block_size = BlockSizeForFileType(file_type); 157 return (size + block_size - 1) / block_size; 158 } 159 160 // Returns true if this address looks like a valid one. 161 bool SanityCheckV2() const; 162 bool SanityCheckV3() const; 163 bool SanityCheckForEntryV2() const; 164 bool SanityCheckForEntryV3() const; 165 bool SanityCheckForRankings() const; 166 167 private: 168 uint32 reserved_bits() const { 169 return value_ & kReservedBitsMask; 170 } 171 172 static const uint32 kInitializedMask = 0x80000000; 173 static const uint32 kFileTypeMask = 0x70000000; 174 static const uint32 kFileTypeOffset = 28; 175 static const uint32 kReservedBitsMask = 0x0c000000; 176 static const uint32 kNumBlocksMask = 0x03000000; 177 static const uint32 kNumBlocksOffset = 24; 178 static const uint32 kFileSelectorMask = 0x00ff0000; 179 static const uint32 kFileSelectorOffset = 16; 180 static const uint32 kStartBlockMask = 0x0000FFFF; 181 static const uint32 kFileNameMask = 0x0FFFFFFF; 182 183 CacheAddr value_; 184 }; 185 186 } // namespace disk_cache 187 188 #endif // NET_DISK_CACHE_BLOCKFILE_ADDR_H_ 189