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