1// Copyright (c) 2006-2008 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_ADDR_H_
9#define NET_DISK_CACHE_ADDR_H_
10
11#include "net/disk_cache/disk_format.h"
12
13namespace disk_cache {
14
15enum FileType {
16  EXTERNAL = 0,
17  RANKINGS = 1,
18  BLOCK_256,
19  BLOCK_1K,
20  BLOCK_4K,
21};
22
23const int kMaxBlockSize = 4096 * 4;
24const int kMaxBlockFile = 255;
25const int kMaxNumBlocks = 4;
26const int kFirstAdditionlBlockFile = 4;
27
28// Defines a storage address for a cache record
29//
30// Header:
31//   1000 0000 0000 0000 0000 0000 0000 0000 : initialized bit
32//   0111 0000 0000 0000 0000 0000 0000 0000 : file type
33//
34// File type values:
35//   0 = separate file on disk
36//   1 = rankings block file
37//   2 = 256 byte block file
38//   3 = 1k byte block file
39//   4 = 4k byte block file
40//
41// If separate file:
42//   0000 1111 1111 1111 1111 1111 1111 1111 : file#  0 - 268,435,456 (2^28)
43//
44// If block file:
45//   0000 1100 0000 0000 0000 0000 0000 0000 : reserved bits
46//   0000 0011 0000 0000 0000 0000 0000 0000 : number of contiguous blocks 1-4
47//   0000 0000 1111 1111 0000 0000 0000 0000 : file selector 0 - 255
48//   0000 0000 0000 0000 1111 1111 1111 1111 : block#  0 - 65,535 (2^16)
49class Addr {
50 public:
51  Addr() : value_(0) {}
52  explicit Addr(CacheAddr address) : value_(address) {}
53  Addr(FileType file_type, int max_blocks, int block_file, int index) {
54    value_ = ((file_type << kFileTypeOffset) & kFileTypeMask) |
55             (((max_blocks - 1) << kNumBlocksOffset) & kNumBlocksMask) |
56             ((block_file << kFileSelectorOffset) & kFileSelectorMask) |
57             (index  & kStartBlockMask) | kInitializedMask;
58  }
59
60  CacheAddr value() const { return value_; }
61  void set_value(CacheAddr address) {
62    value_ = address;
63  }
64
65  bool is_initialized() const {
66    return (value_ & kInitializedMask) != 0;
67  }
68
69  bool is_separate_file() const {
70    return (value_ & kFileTypeMask) == 0;
71  }
72
73  bool is_block_file() const {
74    return !is_separate_file();
75  }
76
77  FileType file_type() const {
78    return static_cast<FileType>((value_ & kFileTypeMask) >> kFileTypeOffset);
79  }
80
81  int FileNumber() const {
82    if (is_separate_file())
83      return value_ & kFileNameMask;
84    else
85      return ((value_ & kFileSelectorMask) >> kFileSelectorOffset);
86  }
87
88  int start_block() const;
89  int num_blocks() const;
90  bool SetFileNumber(int file_number);
91  int BlockSize() const {
92    return BlockSizeForFileType(file_type());
93  }
94
95  static int BlockSizeForFileType(FileType file_type) {
96    switch (file_type) {
97      case RANKINGS:
98        return 36;
99      case BLOCK_256:
100        return 256;
101      case BLOCK_1K:
102        return 1024;
103      case BLOCK_4K:
104        return 4096;
105      default:
106        return 0;
107    }
108  }
109
110  static FileType RequiredFileType(int size) {
111    if (size < 1024)
112      return BLOCK_256;
113    else if (size < 4096)
114      return BLOCK_1K;
115    else if (size <= 4096 * 4)
116      return BLOCK_4K;
117    else
118      return EXTERNAL;
119  }
120
121 private:
122  static const uint32 kInitializedMask    = 0x80000000;
123  static const uint32 kFileTypeMask       = 0x70000000;
124  static const uint32 kFileTypeOffset     = 28;
125  static const uint32 kNumBlocksMask      = 0x03000000;
126  static const uint32 kNumBlocksOffset    = 24;
127  static const uint32 kFileSelectorMask   = 0x00ff0000;
128  static const uint32 kFileSelectorOffset = 16;
129  static const uint32 kStartBlockMask     = 0x0000FFFF;
130  static const uint32 kFileNameMask       = 0x0FFFFFFF;
131
132  CacheAddr value_;
133};
134
135}  // namespace disk_cache
136
137#endif  // NET_DISK_CACHE_ADDR_H_
138