diff options
Diffstat (limited to 'net/disk_cache/blockfile/addr.h')
-rw-r--r-- | net/disk_cache/blockfile/addr.h | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/net/disk_cache/blockfile/addr.h b/net/disk_cache/blockfile/addr.h new file mode 100644 index 0000000..99d2c93 --- /dev/null +++ b/net/disk_cache/blockfile/addr.h @@ -0,0 +1,188 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This is an internal class that handles the address of a cache record. +// See net/disk_cache/disk_cache.h for the public interface of the cache. + +#ifndef NET_DISK_CACHE_BLOCKFILE_ADDR_H_ +#define NET_DISK_CACHE_BLOCKFILE_ADDR_H_ + +#include "net/base/net_export.h" +#include "net/disk_cache/blockfile/disk_format_base.h" + +namespace disk_cache { + +enum FileType { + EXTERNAL = 0, + RANKINGS = 1, + BLOCK_256 = 2, + BLOCK_1K = 3, + BLOCK_4K = 4, + BLOCK_FILES = 5, + BLOCK_ENTRIES = 6, + BLOCK_EVICTED = 7 +}; + +const int kMaxBlockSize = 4096 * 4; +const int kMaxBlockFile = 255; +const int kMaxNumBlocks = 4; +const int kFirstAdditionalBlockFile = 4; +const int kFirstAdditionalBlockFileV3 = 7; + +// Defines a storage address for a cache record +// +// Header: +// 1000 0000 0000 0000 0000 0000 0000 0000 : initialized bit +// 0111 0000 0000 0000 0000 0000 0000 0000 : file type +// +// File type values: +// 0 = separate file on disk +// 1 = rankings block file +// 2 = 256 byte block file +// 3 = 1k byte block file +// 4 = 4k byte block file +// 5 = external files block file +// 6 = active entries block file +// 7 = evicted entries block file +// +// If separate file: +// 0000 1111 1111 1111 1111 1111 1111 1111 : file# 0 - 268,435,456 (2^28) +// +// If block file: +// 0000 1100 0000 0000 0000 0000 0000 0000 : reserved bits +// 0000 0011 0000 0000 0000 0000 0000 0000 : number of contiguous blocks 1-4 +// 0000 0000 1111 1111 0000 0000 0000 0000 : file selector 0 - 255 +// 0000 0000 0000 0000 1111 1111 1111 1111 : block# 0 - 65,535 (2^16) +// +// Note that an Addr can be used to "point" to a variety of different objects, +// from a given type of entry to random blobs of data. Conceptually, an Addr is +// just a number that someone can inspect to find out how to locate the desired +// record. Most users will not care about the specific bits inside Addr, for +// example, what parts of it point to a file number; only the code that has to +// select a specific file would care about those specific bits. +// +// From a general point of view, an Addr has a total capacity of 2^24 entities, +// in that it has 24 bits that can identify individual records. Note that the +// address space is bigger for independent files (2^28), but that would not be +// the general case. +class NET_EXPORT_PRIVATE Addr { + public: + Addr() : value_(0) {} + explicit Addr(CacheAddr address) : value_(address) {} + Addr(FileType file_type, int max_blocks, int block_file, int index) { + value_ = ((file_type << kFileTypeOffset) & kFileTypeMask) | + (((max_blocks - 1) << kNumBlocksOffset) & kNumBlocksMask) | + ((block_file << kFileSelectorOffset) & kFileSelectorMask) | + (index & kStartBlockMask) | kInitializedMask; + } + + CacheAddr value() const { return value_; } + void set_value(CacheAddr address) { + value_ = address; + } + + bool is_initialized() const { + return (value_ & kInitializedMask) != 0; + } + + bool is_separate_file() const { + return (value_ & kFileTypeMask) == 0; + } + + bool is_block_file() const { + return !is_separate_file(); + } + + FileType file_type() const { + return static_cast<FileType>((value_ & kFileTypeMask) >> kFileTypeOffset); + } + + int FileNumber() const { + if (is_separate_file()) + return value_ & kFileNameMask; + else + return ((value_ & kFileSelectorMask) >> kFileSelectorOffset); + } + + int start_block() const; + int num_blocks() const; + bool SetFileNumber(int file_number); + int BlockSize() const { + return BlockSizeForFileType(file_type()); + } + + bool operator==(Addr other) const { + return value_ == other.value_; + } + + bool operator!=(Addr other) const { + return value_ != other.value_; + } + + static int BlockSizeForFileType(FileType file_type) { + switch (file_type) { + case RANKINGS: + return 36; + case BLOCK_256: + return 256; + case BLOCK_1K: + return 1024; + case BLOCK_4K: + return 4096; + case BLOCK_FILES: + return 8; + case BLOCK_ENTRIES: + return 104; + case BLOCK_EVICTED: + return 48; + default: + return 0; + } + } + + static FileType RequiredFileType(int size) { + if (size < 1024) + return BLOCK_256; + else if (size < 4096) + return BLOCK_1K; + else if (size <= 4096 * 4) + return BLOCK_4K; + else + return EXTERNAL; + } + + static int RequiredBlocks(int size, FileType file_type) { + int block_size = BlockSizeForFileType(file_type); + return (size + block_size - 1) / block_size; + } + + // Returns true if this address looks like a valid one. + bool SanityCheckV2() const; + bool SanityCheckV3() const; + bool SanityCheckForEntryV2() const; + bool SanityCheckForEntryV3() const; + bool SanityCheckForRankings() const; + + private: + uint32 reserved_bits() const { + return value_ & kReservedBitsMask; + } + + static const uint32 kInitializedMask = 0x80000000; + static const uint32 kFileTypeMask = 0x70000000; + static const uint32 kFileTypeOffset = 28; + static const uint32 kReservedBitsMask = 0x0c000000; + static const uint32 kNumBlocksMask = 0x03000000; + static const uint32 kNumBlocksOffset = 24; + static const uint32 kFileSelectorMask = 0x00ff0000; + static const uint32 kFileSelectorOffset = 16; + static const uint32 kStartBlockMask = 0x0000FFFF; + static const uint32 kFileNameMask = 0x0FFFFFFF; + + CacheAddr value_; +}; + +} // namespace disk_cache + +#endif // NET_DISK_CACHE_BLOCKFILE_ADDR_H_ |