1// Copyright (c) 2013 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#ifndef NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
6#define NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
7
8#include <algorithm>
9#include <string>
10#include <utility>
11#include <vector>
12
13#include "base/files/file_path.h"
14#include "base/memory/scoped_ptr.h"
15#include "base/platform_file.h"
16#include "base/time/time.h"
17#include "net/disk_cache/simple/simple_entry_format.h"
18
19namespace net {
20class IOBuffer;
21}
22
23namespace disk_cache {
24
25class SimpleSynchronousEntry;
26
27struct SimpleEntryStat {
28  SimpleEntryStat();
29  SimpleEntryStat(base::Time last_used_p,
30                  base::Time last_modified_p,
31                  const int32 data_size_p[]);
32
33  base::Time last_used;
34  base::Time last_modified;
35  int32 data_size[kSimpleEntryFileCount];
36};
37
38struct SimpleEntryCreationResults {
39  SimpleEntryCreationResults(SimpleEntryStat entry_stat);
40  ~SimpleEntryCreationResults();
41
42  SimpleSynchronousEntry* sync_entry;
43  SimpleEntryStat entry_stat;
44  int result;
45};
46
47// Worker thread interface to the very simple cache. This interface is not
48// thread safe, and callers must ensure that it is only ever accessed from
49// a single thread between synchronization points.
50class SimpleSynchronousEntry {
51 public:
52  struct CRCRecord {
53    CRCRecord();
54    CRCRecord(int index_p, bool has_crc32_p, uint32 data_crc32_p);
55
56    int index;
57    bool has_crc32;
58    uint32 data_crc32;
59  };
60
61  struct EntryOperationData {
62    EntryOperationData(int index_p, int offset_p, int buf_len_p);
63    EntryOperationData(int index_p,
64                       int offset_p,
65                       int buf_len_p,
66                       bool truncate_p);
67
68    int index;
69    int offset;
70    int buf_len;
71    bool truncate;
72  };
73
74  static void OpenEntry(const base::FilePath& path,
75                        uint64 entry_hash,
76                        bool had_index,
77                        SimpleEntryCreationResults* out_results);
78
79  static void CreateEntry(const base::FilePath& path,
80                          const std::string& key,
81                          uint64 entry_hash,
82                          bool had_index,
83                          SimpleEntryCreationResults* out_results);
84
85  // Deletes an entry without first Opening it. Does not check if there is
86  // already an Entry object in memory holding the open files. Be careful! This
87  // is meant to be used by the Backend::DoomEntry() call. |callback| will be
88  // run by |callback_runner|.
89  static void DoomEntry(const base::FilePath& path,
90                        const std::string& key,
91                        uint64 entry_hash,
92                        int* out_result);
93
94  // Like |DoomEntry()| above. Deletes all entries corresponding to the
95  // |key_hashes|. Succeeds only when all entries are deleted. Returns a net
96  // error code.
97  static int DoomEntrySet(scoped_ptr<std::vector<uint64> > key_hashes,
98                          const base::FilePath& path);
99
100  // N.B. ReadData(), WriteData(), CheckEOFRecord() and Close() may block on IO.
101  void ReadData(const EntryOperationData& in_entry_op,
102                net::IOBuffer* out_buf,
103                uint32* out_crc32,
104                base::Time* out_last_used,
105                int* out_result) const;
106  void WriteData(const EntryOperationData& in_entry_op,
107                 net::IOBuffer* in_buf,
108                 SimpleEntryStat* out_entry_stat,
109                 int* out_result) const;
110  void CheckEOFRecord(int index,
111                      int data_size,
112                      uint32 expected_crc32,
113                      int* out_result) const;
114
115  // Close all streams, and add write EOF records to streams indicated by the
116  // CRCRecord entries in |crc32s_to_write|.
117  void Close(const SimpleEntryStat& entry_stat,
118             scoped_ptr<std::vector<CRCRecord> > crc32s_to_write);
119
120  const base::FilePath& path() const { return path_; }
121  std::string key() const { return key_; }
122
123 private:
124  SimpleSynchronousEntry(
125      const base::FilePath& path,
126      const std::string& key,
127      uint64 entry_hash);
128
129  // Like Entry, the SimpleSynchronousEntry self releases when Close() is
130  // called.
131  ~SimpleSynchronousEntry();
132
133  bool OpenOrCreateFiles(bool create,
134                         bool had_index,
135                         SimpleEntryStat* out_entry_stat);
136  void CloseFiles();
137
138  // Returns a net error, i.e. net::OK on success.  |had_index| is passed
139  // from the main entry for metrics purposes, and is true if the index was
140  // initialized when the open operation began.
141  int InitializeForOpen(bool had_index, SimpleEntryStat* out_entry_stat);
142
143  // Returns a net error, including net::OK on success and net::FILE_EXISTS
144  // when the entry already exists.  |had_index| is passed from the main entry
145  // for metrics purposes, and is true if the index was initialized when the
146  // create operation began.
147  int InitializeForCreate(bool had_index, SimpleEntryStat* out_entry_stat);
148
149  void Doom() const;
150
151  static bool DeleteFilesForEntryHash(const base::FilePath& path,
152                                      uint64 entry_hash);
153
154  const base::FilePath path_;
155  const uint64 entry_hash_;
156  std::string key_;
157
158  bool have_open_files_;
159  bool initialized_;
160
161  base::PlatformFile files_[kSimpleEntryFileCount];
162};
163
164}  // namespace disk_cache
165
166#endif  // NET_DISK_CACHE_SIMPLE_SIMPLE_SYNCHRONOUS_ENTRY_H_
167