summaryrefslogtreecommitdiffstats
path: root/net/disk_cache/blockfile/addr.h
diff options
context:
space:
mode:
Diffstat (limited to 'net/disk_cache/blockfile/addr.h')
-rw-r--r--net/disk_cache/blockfile/addr.h188
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_