Home | History | Annotate | Download | only in blockfile
      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