File: simple_index_file.h

package info (click to toggle)
chromium 139.0.7258.127-2
  • links: PTS, VCS
  • area: main
  • in suites: forky
  • size: 6,122,156 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (206 lines) | stat: -rw-r--r-- 8,396 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_
#define NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_

#include <stdint.h>

#include <memory>
#include <vector>

#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/pickle.h"
#include "net/base/cache_type.h"
#include "net/base/net_export.h"
#include "net/disk_cache/simple/simple_backend_version.h"
#include "net/disk_cache/simple/simple_index.h"

namespace base {
class SequencedTaskRunner;
}

namespace disk_cache {
class BackendFileOperations;
class BackendFileOperationsFactory;

const uint64_t kSimpleIndexMagicNumber = UINT64_C(0x656e74657220796f);

struct NET_EXPORT_PRIVATE SimpleIndexLoadResult {
  SimpleIndexLoadResult();
  ~SimpleIndexLoadResult();
  void Reset();

  bool did_load = false;
  SimpleIndex::EntrySet entries;
  SimpleIndex::IndexWriteToDiskReason index_write_reason =
      SimpleIndex::INDEX_WRITE_REASON_MAX;
  SimpleIndex::IndexInitMethod init_method;
  bool flush_required = false;
};

// Simple Index File format is a pickle of IndexMetadata and EntryMetadata
// objects. The file format is as follows: one instance of |IndexMetadata|
// followed by |EntryMetadata| repeated |entry_count| times. To learn more about
// the format see |SimpleIndexFile::Serialize()| and
// |SimpleIndexFile::LoadFromDisk()|.
//
// The non-static methods must run on the source creation sequence. All the real
// work is done in the static methods, which are run on the cache thread
// or in worker threads. Synchronization between methods is the
// responsibility of the caller.
class NET_EXPORT_PRIVATE SimpleIndexFile {
 public:
  class NET_EXPORT_PRIVATE IndexMetadata {
   public:
    IndexMetadata();
    IndexMetadata(SimpleIndex::IndexWriteToDiskReason reason,
                  uint64_t entry_count,
                  uint64_t cache_size);

    virtual void Serialize(base::Pickle* pickle) const;
    bool Deserialize(base::PickleIterator* it);

    bool CheckIndexMetadata();

    SimpleIndex::IndexWriteToDiskReason reason() const { return reason_; }
    uint64_t entry_count() const { return entry_count_; }
    bool app_cache_has_trailer_prefetch_size() const { return version_ >= 9; }

   private:
    FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Basics);
    FRIEND_TEST_ALL_PREFIXES(IndexMetadataTest, Serialize);
    FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8Format);
    FRIEND_TEST_ALL_PREFIXES(SimpleIndexFileTest, ReadV8FormatAppCache);
    friend class V8IndexMetadataForTest;

    uint64_t magic_number_ = kSimpleIndexMagicNumber;
    uint32_t version_ = kSimpleIndexFileVersion;
    SimpleIndex::IndexWriteToDiskReason reason_;
    uint64_t entry_count_;
    uint64_t cache_size_;  // Total cache storage size in bytes.
  };

  SimpleIndexFile(
      scoped_refptr<base::SequencedTaskRunner> cache_runner,
      scoped_refptr<BackendFileOperationsFactory> file_operations_factory,
      net::CacheType cache_type,
      const base::FilePath& cache_directory);

  SimpleIndexFile(const SimpleIndexFile&) = delete;
  SimpleIndexFile& operator=(const SimpleIndexFile&) = delete;

  virtual ~SimpleIndexFile();

  // Gets index entries based on current disk context. On error it may leave
  // |out_result.did_load| untouched, but still return partial and consistent
  // results in |out_result.entries|.
  virtual void LoadIndexEntries(base::Time cache_last_modified,
                                base::OnceClosure callback,
                                SimpleIndexLoadResult* out_result);

  // Writes the specified set of entries to disk.
  virtual void WriteToDisk(net::CacheType cache_type,
                           SimpleIndex::IndexWriteToDiskReason reason,
                           const SimpleIndex::EntrySet& entry_set,
                           uint64_t cache_size,
                           base::OnceClosure callback);

 private:
  friend class WrappedSimpleIndexFile;

  // Used for cache directory traversal.
  using EntryFileCallback =
      base::RepeatingCallback<void(const base::FilePath&,
                                   base::Time last_accessed,
                                   base::Time last_modified,
                                   int64_t size)>;

  // When loading the entries from disk, add this many extra hash buckets to
  // prevent reallocation on the creation sequence when merging in new live
  // entries.
  static const int kExtraSizeForMerge = 512;

  // Synchronous (IO performing) implementation of LoadIndexEntries.
  static void SyncLoadIndexEntries(
      std::unique_ptr<BackendFileOperations> file_operations,
      net::CacheType cache_type,
      base::Time cache_last_modified,
      const base::FilePath& cache_directory,
      const base::FilePath& index_file_path,
      SimpleIndexLoadResult* out_result);

  // Load the index file from disk returning an EntrySet.
  static void SyncLoadFromDisk(BackendFileOperations* file_operations,
                               net::CacheType cache_type,
                               const base::FilePath& index_filename,
                               base::Time* out_last_cache_seen_by_index,
                               SimpleIndexLoadResult* out_result);

  // Returns a scoped_ptr for a newly allocated base::Pickle containing the
  // serialized
  // data to be written to a file. Note: the pickle is not in a consistent state
  // immediately after calling this menthod, one needs to call
  // SerializeFinalData to make it ready to write to a file.
  static std::unique_ptr<base::Pickle> Serialize(
      net::CacheType cache_type,
      const SimpleIndexFile::IndexMetadata& index_metadata,
      const SimpleIndex::EntrySet& entries);

  // Appends cache modification time data to the serialized format. This is
  // performed on a thread accessing the disk. It is not combined with the main
  // serialization path to avoid extra thread hops or copying the pickle to the
  // worker thread.
  static void SerializeFinalData(base::Time cache_modified,
                                 base::Pickle* pickle);

  // Given the contents of an index file `data`, returns the corresponding
  // EntrySet and associated metadata. `out_result->did_load` will return
  // whether successful or not.
  static void Deserialize(net::CacheType cache_type,
                          base::span<const uint8_t> data,
                          base::Time* out_cache_last_modified,
                          SimpleIndexLoadResult* out_result);

  // Writes the index file to disk atomically.
  static void SyncWriteToDisk(
      std::unique_ptr<BackendFileOperations> file_operations,
      net::CacheType cache_type,
      const base::FilePath& cache_directory,
      const base::FilePath& index_filename,
      const base::FilePath& temp_index_filename,
      std::unique_ptr<base::Pickle> pickle);

  // Scan the index directory for entries, returning an EntrySet of all entries
  // found.
  static void SyncRestoreFromDisk(BackendFileOperations* file_operations,
                                  net::CacheType cache_type,
                                  const base::FilePath& cache_directory,
                                  const base::FilePath& index_file_path,
                                  SimpleIndexLoadResult* out_result);

  // Determines if an index file is stale relative to the time of last
  // modification of the cache directory. Obsolete, used only for a histogram to
  // compare with the new method.
  // TODO(pasko): remove this method after getting enough data.
  static bool LegacyIsIndexFileStale(BackendFileOperations* file_operations,
                                     base::Time cache_last_modified,
                                     const base::FilePath& index_file_path);

  const scoped_refptr<base::SequencedTaskRunner> cache_runner_;
  const scoped_refptr<BackendFileOperationsFactory> file_operations_factory_;
  const net::CacheType cache_type_;
  const base::FilePath cache_directory_;
  const base::FilePath index_file_;
  const base::FilePath temp_index_file_;

  static const char kIndexDirectory[];
  static const char kIndexFileName[];
  static const char kTempIndexFileName[];
};

}  // namespace disk_cache

#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_INDEX_FILE_H_