OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // The cache is stored on disk as a collection of block-files, plus an index | 5 // The cache is stored on disk as a collection of block-files, plus an index |
6 // file plus a collection of external files. | 6 // file plus a collection of external files. |
7 // | 7 // |
8 // Any data blob bigger than kMaxBlockSize (net/addr.h) will be stored on a | 8 // Any data blob bigger than kMaxBlockSize (net/addr.h) will be stored on a |
9 // separate file named f_xxx where x is a hexadecimal number. Shorter data will | 9 // separate file named f_xxx where x is a hexadecimal number. Shorter data will |
10 // be stored as a series of blocks on a block-file. In any case, CacheAddr | 10 // be stored as a series of blocks on a block-file. In any case, CacheAddr |
11 // represents the address of the data inside the cache. | 11 // represents the address of the data inside the cache. |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
183 AllocBitmap allocation_map; | 183 AllocBitmap allocation_map; |
184 BlockFileHeader() { | 184 BlockFileHeader() { |
185 memset(this, 0, sizeof(BlockFileHeader)); | 185 memset(this, 0, sizeof(BlockFileHeader)); |
186 magic = kBlockMagic; | 186 magic = kBlockMagic; |
187 version = kCurrentVersion; | 187 version = kCurrentVersion; |
188 }; | 188 }; |
189 }; | 189 }; |
190 | 190 |
191 COMPILE_ASSERT(sizeof(BlockFileHeader) == kBlockHeaderSize, bad_header); | 191 COMPILE_ASSERT(sizeof(BlockFileHeader) == kBlockHeaderSize, bad_header); |
192 | 192 |
| 193 // Sparse data support: |
| 194 // We keep a two level hierarchy to enable sparse data for an entry: the first |
| 195 // level consists of using separate "child" entries to store ranges of 1 MB, |
| 196 // and the second level stores blocks of 1 KB inside each child entry. |
| 197 // |
| 198 // Whenever we need to access a particular sparse offset, we first locate the |
| 199 // child entry that stores that offset, so we discard the 20 least significant |
| 200 // bits of the offset, and end up with the child id. For instance, the child id |
| 201 // to store the first megabyte is 0, and the child that should store offset |
| 202 // 0x410000 has an id of 4. |
| 203 // |
| 204 // The child entry is stored the same way as any other entry, so it also has a |
| 205 // name (key). The key includes a signature to be able to identify children |
| 206 // created for different generations of the same resource. In other words, given |
| 207 // that a given sparse entry can have a large number of child entries, and the |
| 208 // resource can be invalidated and replaced with a new version at any time, it |
| 209 // is important to be sure that a given child actually belongs to certain entry. |
| 210 // |
| 211 // The full name of a child entry is composed with a prefix ("Range_"), and two |
| 212 // hexadecimal 64-bit numbers at the end, separated by semicolons. The first |
| 213 // number is the signature of the parent key, and the second number is the child |
| 214 // id as described previously. The signature itself is also stored internally by |
| 215 // the child and the parent entries. For example, a sparse entry with a key of |
| 216 // "sparse entry name", and a signature of 0x052AF76, may have a child entry |
| 217 // named "Range_sparse entry name:052af76:4", which stores data in the range |
| 218 // 0x400000 to 0x4FFFFF. |
| 219 // |
| 220 // Each child entry keeps track of all the 1 KB blocks that have been written |
| 221 // to the entry, but being a regular entry, it will happily return zeros for any |
| 222 // read that spans data not written before. The actual sparse data is stored in |
| 223 // one of the data streams of the child entry (at index 1), while the control |
| 224 // information is stored in another stream (at index 2), both by parents and |
| 225 // the children. |
| 226 |
| 227 // This structure contains the control information for parent and child entries. |
| 228 // It is stored at offset 0 of the data stream with index 2. |
| 229 struct SparseHeader { |
| 230 int64 signature; // The parent and children signature. |
| 231 uint32 magic; // Structure identifier (equal to kIndexMagic). |
| 232 int32 parent_key_len; // Key length for the parent entry. |
| 233 int32 dummy[4]; |
| 234 }; |
| 235 |
| 236 // The SparseHeader will be followed by a bitmap, as described by this |
| 237 // structure. |
| 238 struct SparseData { |
| 239 SparseHeader header; |
| 240 uint32 bitmap[32]; // Bitmap representation of known children (if this |
| 241 // is a parent entry), or used blocks (for child |
| 242 // entries. The size is fixed for child entries but |
| 243 // not for parents; it can be as small as 4 bytes |
| 244 // and as large as 8 KB. |
| 245 }; |
| 246 |
| 247 // The number of blocks stored by a child entry. |
| 248 const int kNumSparseBits = 1024; |
| 249 COMPILE_ASSERT(sizeof(SparseData) == sizeof(SparseHeader) + kNumSparseBits / 8, |
| 250 Invalid_SparseData_bitmap); |
| 251 |
193 } // namespace disk_cache | 252 } // namespace disk_cache |
194 | 253 |
195 #endif // NET_DISK_CACHE_DISK_FORMAT_H_ | 254 #endif // NET_DISK_CACHE_DISK_FORMAT_H_ |
OLD | NEW |