15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is an internal class that handles the address of a cache record.
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// See net/disk_cache/disk_cache.h for the public interface of the cache.
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#ifndef NET_DISK_CACHE_BLOCKFILE_ADDR_H_
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#define NET_DISK_CACHE_BLOCKFILE_ADDR_H_
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_export.h"
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "net/disk_cache/blockfile/disk_format_base.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace disk_cache {
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum FileType {
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXTERNAL = 0,
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RANKINGS = 1,
19eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BLOCK_256 = 2,
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BLOCK_1K = 3,
21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BLOCK_4K = 4,
22eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BLOCK_FILES = 5,
23eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BLOCK_ENTRIES = 6,
24eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  BLOCK_EVICTED = 7
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxBlockSize = 4096 * 4;
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxBlockFile = 255;
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kMaxNumBlocks = 4;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kFirstAdditionalBlockFile = 4;
31eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst int kFirstAdditionalBlockFileV3 = 7;
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defines a storage address for a cache record
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Header:
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   1000 0000 0000 0000 0000 0000 0000 0000 : initialized bit
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0111 0000 0000 0000 0000 0000 0000 0000 : file type
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// File type values:
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0 = separate file on disk
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   1 = rankings block file
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   2 = 256 byte block file
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   3 = 1k byte block file
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   4 = 4k byte block file
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//   5 = external files block file
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//   6 = active entries block file
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch//   7 = evicted entries block file
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If separate file:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0000 1111 1111 1111 1111 1111 1111 1111 : file#  0 - 268,435,456 (2^28)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If block file:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0000 1100 0000 0000 0000 0000 0000 0000 : reserved bits
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0000 0011 0000 0000 0000 0000 0000 0000 : number of contiguous blocks 1-4
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0000 0000 1111 1111 0000 0000 0000 0000 : file selector 0 - 255
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   0000 0000 0000 0000 1111 1111 1111 1111 : block#  0 - 65,535 (2^16)
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Note that an Addr can be used to "point" to a variety of different objects,
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// from a given type of entry to random blobs of data. Conceptually, an Addr is
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// just a number that someone can inspect to find out how to locate the desired
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// record. Most users will not care about the specific bits inside Addr, for
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// example, what parts of it point to a file number; only the code that has to
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// select a specific file would care about those specific bits.
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)//
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// From a general point of view, an Addr has a total capacity of 2^24 entities,
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// in that it has 24 bits that can identify individual records. Note that the
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// address space is bigger for independent files (2^28), but that would not be
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// the general case.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NET_EXPORT_PRIVATE Addr {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Addr() : value_(0) {}
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit Addr(CacheAddr address) : value_(address) {}
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Addr(FileType file_type, int max_blocks, int block_file, int index) {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value_ = ((file_type << kFileTypeOffset) & kFileTypeMask) |
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             (((max_blocks - 1) << kNumBlocksOffset) & kNumBlocksMask) |
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             ((block_file << kFileSelectorOffset) & kFileSelectorMask) |
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             (index  & kStartBlockMask) | kInitializedMask;
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CacheAddr value() const { return value_; }
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_value(CacheAddr address) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    value_ = address;
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_initialized() const {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (value_ & kInitializedMask) != 0;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_separate_file() const {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (value_ & kFileTypeMask) == 0;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool is_block_file() const {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return !is_separate_file();
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FileType file_type() const {
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return static_cast<FileType>((value_ & kFileTypeMask) >> kFileTypeOffset);
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int FileNumber() const {
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (is_separate_file())
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return value_ & kFileNameMask;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ((value_ & kFileSelectorMask) >> kFileSelectorOffset);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int start_block() const;
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int num_blocks() const;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SetFileNumber(int file_number);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int BlockSize() const {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return BlockSizeForFileType(file_type());
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator==(Addr other) const {
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value_ == other.value_;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool operator!=(Addr other) const {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return value_ != other.value_;
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static int BlockSizeForFileType(FileType file_type) {
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (file_type) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case RANKINGS:
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 36;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case BLOCK_256:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 256;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case BLOCK_1K:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 1024;
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case BLOCK_4K:
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 4096;
133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case BLOCK_FILES:
134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return 8;
135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case BLOCK_ENTRIES:
136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return 104;
137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      case BLOCK_EVICTED:
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        return 48;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return 0;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static FileType RequiredFileType(int size) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (size < 1024)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return BLOCK_256;
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (size < 4096)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return BLOCK_1K;
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (size <= 4096 * 4)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return BLOCK_4K;
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return EXTERNAL;
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  static int RequiredBlocks(int size, FileType file_type) {
15690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    int block_size = BlockSizeForFileType(file_type);
15790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    return (size + block_size - 1) / block_size;
15890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  }
15990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns true if this address looks like a valid one.
161eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool SanityCheckV2() const;
162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool SanityCheckV3() const;
163868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  bool SanityCheckForEntryV2() const;
164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool SanityCheckForEntryV3() const;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool SanityCheckForRankings() const;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  uint32 reserved_bits() const {
169eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return value_ & kReservedBitsMask;
170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
171eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kInitializedMask    = 0x80000000;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kFileTypeMask       = 0x70000000;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kFileTypeOffset     = 28;
175eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  static const uint32 kReservedBitsMask   = 0x0c000000;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kNumBlocksMask      = 0x03000000;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kNumBlocksOffset    = 24;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kFileSelectorMask   = 0x00ff0000;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kFileSelectorOffset = 16;
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kStartBlockMask     = 0x0000FFFF;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const uint32 kFileNameMask       = 0x0FFFFFFF;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CacheAddr value_;
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace disk_cache
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
188a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif  // NET_DISK_CACHE_BLOCKFILE_ADDR_H_
189