Make NetworkCache::traverse faster
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / cache / NetworkCacheStorage.h
1 /*
2  * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #ifndef NetworkCacheStorage_h
27 #define NetworkCacheStorage_h
28
29 #if ENABLE(NETWORK_CACHE)
30
31 #include "NetworkCacheBlobStorage.h"
32 #include "NetworkCacheData.h"
33 #include "NetworkCacheKey.h"
34 #include <WebCore/Timer.h>
35 #include <wtf/BloomFilter.h>
36 #include <wtf/Deque.h>
37 #include <wtf/HashSet.h>
38 #include <wtf/Optional.h>
39 #include <wtf/WorkQueue.h>
40 #include <wtf/text/WTFString.h>
41
42 namespace WebKit {
43 namespace NetworkCache {
44
45 class IOChannel;
46
47 class Storage {
48     WTF_MAKE_NONCOPYABLE(Storage);
49 public:
50     static std::unique_ptr<Storage> open(const String& cachePath);
51
52     struct Record {
53         Key key;
54         std::chrono::system_clock::time_point timeStamp;
55         Data header;
56         Data body;
57     };
58     // This may call completion handler synchronously on failure.
59     typedef std::function<bool (std::unique_ptr<Record>)> RetrieveCompletionHandler;
60     void retrieve(const Key&, unsigned priority, RetrieveCompletionHandler&&);
61
62     typedef std::function<void (const Data& mappedBody)> MappedBodyHandler;
63     void store(const Record&, MappedBodyHandler&&);
64
65     void remove(const Key&);
66     void clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
67
68     struct RecordInfo {
69         size_t bodySize;
70         double worth; // 0-1 where 1 is the most valuable.
71         unsigned bodyShareCount;
72         String bodyHash;
73     };
74     enum TraverseFlag {
75         ComputeWorth = 1 << 0,
76         ShareCount = 1 << 1,
77     };
78     typedef unsigned TraverseFlags;
79     typedef std::function<void (const Record*, const RecordInfo&)> TraverseHandler;
80     // Null record signals end.
81     void traverse(TraverseFlags, TraverseHandler&&);
82
83     void clearWriteQueue();
84
85     void setCapacity(size_t);
86     size_t capacity() const { return m_capacity; }
87     size_t approximateSize() const;
88
89     static const unsigned version = 4;
90
91     String basePath() const;
92     String versionPath() const;
93     String recordsPath() const;
94
95     ~Storage();
96
97 private:
98     Storage(const String& directoryPath);
99
100     String partitionPathForKey(const Key&) const;
101     String recordPathForKey(const Key&) const;
102     String bodyPathForKey(const Key&) const;
103
104     void synchronize();
105     void deleteOldVersions();
106     void shrinkIfNeeded();
107     void shrink();
108
109     struct ReadOperation;
110     void dispatchReadOperation(ReadOperation&);
111     void dispatchPendingReadOperations();
112     void finishReadOperation(ReadOperation&);
113
114     struct WriteOperation;
115     void dispatchWriteOperation(WriteOperation&);
116     void dispatchPendingWriteOperations();
117     void finishWriteOperation(WriteOperation&);
118
119     Optional<BlobStorage::Blob> storeBodyAsBlob(WriteOperation&);
120     Data encodeRecord(const Record&, Optional<BlobStorage::Blob>);
121     void readRecord(ReadOperation&, const Data&);
122
123     void updateFileModificationTime(const String& path);
124
125     WorkQueue& ioQueue() { return m_ioQueue.get(); }
126     WorkQueue& backgroundIOQueue() { return m_backgroundIOQueue.get(); }
127     WorkQueue& serialBackgroundIOQueue() { return m_serialBackgroundIOQueue.get(); }
128
129     bool mayContain(const Key&) const;
130
131     void addToRecordFilter(const Key&);
132
133     const String m_basePath;
134     const String m_recordsPath;
135
136     size_t m_capacity { std::numeric_limits<size_t>::max() };
137     size_t m_approximateRecordsSize { 0 };
138
139     // 2^18 bit filter can support up to 26000 entries with false positive rate < 1%.
140     using ContentsFilter = BloomFilter<18>;
141     std::unique_ptr<ContentsFilter> m_recordFilter;
142     std::unique_ptr<ContentsFilter> m_bodyFilter;
143
144     bool m_synchronizationInProgress { false };
145     bool m_shrinkInProgress { false };
146
147     Vector<Key::HashType> m_recordFilterHashesAddedDuringSynchronization;
148     Vector<Key::HashType> m_bodyFilterHashesAddedDuringSynchronization;
149
150     static const int maximumRetrievePriority = 4;
151     Deque<std::unique_ptr<ReadOperation>> m_pendingReadOperationsByPriority[maximumRetrievePriority + 1];
152     HashSet<std::unique_ptr<ReadOperation>> m_activeReadOperations;
153
154     Deque<std::unique_ptr<WriteOperation>> m_pendingWriteOperations;
155     HashSet<std::unique_ptr<WriteOperation>> m_activeWriteOperations;
156     WebCore::Timer m_writeOperationDispatchTimer;
157
158     struct TraverseOperation;
159     HashSet<std::unique_ptr<TraverseOperation>> m_activeTraverseOperations;
160
161     Ref<WorkQueue> m_ioQueue;
162     Ref<WorkQueue> m_backgroundIOQueue;
163     Ref<WorkQueue> m_serialBackgroundIOQueue;
164
165     BlobStorage m_blobStorage;
166 };
167
168 // FIXME: Remove, used by NetworkCacheStatistics only.
169 void traverseRecordsFiles(const String& recordsPath, const std::function<void (const String&, const String&)>&);
170
171 }
172 }
173 #endif
174 #endif