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