2 * Copyright (C) 2014-2015 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
26 #ifndef NetworkCacheStorage_h
27 #define NetworkCacheStorage_h
29 #if ENABLE(NETWORK_CACHE)
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>
43 namespace NetworkCache {
48 WTF_MAKE_NONCOPYABLE(Storage);
50 static std::unique_ptr<Storage> open(const String& cachePath);
54 std::chrono::system_clock::time_point timeStamp;
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&&);
62 typedef std::function<void (const Data& mappedBody)> MappedBodyHandler;
63 void store(const Record&, MappedBodyHandler&&);
65 void remove(const Key&);
66 void clear(std::chrono::system_clock::time_point modifiedSinceTime, std::function<void ()>&& completionHandler);
70 double worth; // 0-1 where 1 is the most valuable.
71 unsigned bodyShareCount;
75 ComputeWorth = 1 << 0,
78 typedef unsigned TraverseFlags;
79 typedef std::function<void (const Record*, const RecordInfo&)> TraverseHandler;
80 // Null record signals end.
81 void traverse(TraverseFlags, TraverseHandler&&);
83 void clearWriteQueue();
85 void setCapacity(size_t);
86 size_t capacity() const { return m_capacity; }
87 size_t approximateSize() const;
89 static const unsigned version = 4;
91 String basePath() const;
92 String versionPath() const;
93 String recordsPath() const;
98 Storage(const String& directoryPath);
100 String partitionPathForKey(const Key&) const;
101 String recordPathForKey(const Key&) const;
102 String bodyPathForKey(const Key&) const;
105 void deleteOldVersions();
106 void shrinkIfNeeded();
109 struct ReadOperation;
110 void dispatchReadOperation(ReadOperation&);
111 void dispatchPendingReadOperations();
112 void finishReadOperation(ReadOperation&);
114 struct WriteOperation;
115 void dispatchWriteOperation(WriteOperation&);
116 void dispatchPendingWriteOperations();
117 void finishWriteOperation(WriteOperation&);
119 Optional<BlobStorage::Blob> storeBodyAsBlob(WriteOperation&);
120 Data encodeRecord(const Record&, Optional<BlobStorage::Blob>);
121 void readRecord(ReadOperation&, const Data&);
123 void updateFileModificationTime(const String& path);
125 WorkQueue& ioQueue() { return m_ioQueue.get(); }
126 WorkQueue& backgroundIOQueue() { return m_backgroundIOQueue.get(); }
127 WorkQueue& serialBackgroundIOQueue() { return m_serialBackgroundIOQueue.get(); }
129 bool mayContain(const Key&) const;
131 void addToRecordFilter(const Key&);
133 const String m_basePath;
134 const String m_recordsPath;
136 size_t m_capacity { std::numeric_limits<size_t>::max() };
137 size_t m_approximateRecordsSize { 0 };
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;
144 bool m_synchronizationInProgress { false };
145 bool m_shrinkInProgress { false };
147 Vector<Key::HashType> m_recordFilterHashesAddedDuringSynchronization;
148 Vector<Key::HashType> m_bodyFilterHashesAddedDuringSynchronization;
150 static const int maximumRetrievePriority = 4;
151 Deque<std::unique_ptr<ReadOperation>> m_pendingReadOperationsByPriority[maximumRetrievePriority + 1];
152 HashSet<std::unique_ptr<ReadOperation>> m_activeReadOperations;
154 Deque<std::unique_ptr<WriteOperation>> m_pendingWriteOperations;
155 HashSet<std::unique_ptr<WriteOperation>> m_activeWriteOperations;
156 WebCore::Timer m_writeOperationDispatchTimer;
158 struct TraverseOperation;
159 HashSet<std::unique_ptr<TraverseOperation>> m_activeTraverseOperations;
161 Ref<WorkQueue> m_ioQueue;
162 Ref<WorkQueue> m_backgroundIOQueue;
163 Ref<WorkQueue> m_serialBackgroundIOQueue;
165 BlobStorage m_blobStorage;
168 // FIXME: Remove, used by NetworkCacheStatistics only.
169 void traverseRecordsFiles(const String& recordsPath, const std::function<void (const String&, const String&)>&);