23d684d06f4cec45663ae7c012786854a422abeb
[WebKit.git] / Source / WebCore / Modules / indexeddb / server / MemoryIndex.cpp
1 /*
2  * Copyright (C) 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. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "MemoryIndex.h"
28
29 #if ENABLE(INDEXED_DATABASE)
30
31 #include "IDBError.h"
32 #include "IDBGetResult.h"
33 #include "IDBKeyRangeData.h"
34 #include "IndexKey.h"
35 #include "Logging.h"
36 #include "MemoryBackingStoreTransaction.h"
37 #include "MemoryObjectStore.h"
38 #include "ThreadSafeDataBuffer.h"
39
40 namespace WebCore {
41 namespace IDBServer {
42
43 std::unique_ptr<MemoryIndex> MemoryIndex::create(const IDBIndexInfo& info, MemoryObjectStore& objectStore)
44 {
45     return std::make_unique<MemoryIndex>(info, objectStore);
46 }
47
48 MemoryIndex::MemoryIndex(const IDBIndexInfo& info, MemoryObjectStore& objectStore)
49     : m_info(info)
50     , m_objectStore(objectStore)
51 {
52 }
53
54 MemoryIndex::~MemoryIndex()
55 {
56 }
57
58 void MemoryIndex::objectStoreCleared()
59 {
60     auto transaction = m_objectStore.writeTransaction();
61     ASSERT(transaction);
62
63     transaction->indexCleared(*this, WTF::move(m_records));
64 }
65
66 void MemoryIndex::replaceIndexValueStore(std::unique_ptr<IndexValueStore>&& valueStore)
67 {
68     ASSERT(m_objectStore.writeTransaction());
69     ASSERT(m_objectStore.writeTransaction()->isAborting());
70
71     m_records = WTF::move(valueStore);
72 }
73
74 IDBGetResult MemoryIndex::getResultForKeyRange(IndexedDB::IndexRecordType type, const IDBKeyRangeData& range) const
75 {
76     LOG(IndexedDB, "MemoryIndex::getResultForKeyRange");
77
78     if (!m_records)
79         return { };
80
81     IDBKeyData keyToLookFor;
82     if (range.isExactlyOneKey())
83         keyToLookFor = range.lowerKey;
84     else
85         keyToLookFor = m_records->lowestKeyWithRecordInRange(range);
86
87     if (keyToLookFor.isNull())
88         return { };
89
90     const IDBKeyData* keyValue = m_records->lowestValueForKey(keyToLookFor);
91
92     if (!keyValue)
93         return { };
94
95     return type == IndexedDB::IndexRecordType::Key ? IDBGetResult(*keyValue) : IDBGetResult(m_objectStore.valueForKeyRange(*keyValue));
96 }
97
98 uint64_t MemoryIndex::countForKeyRange(const IDBKeyRangeData& inRange)
99 {
100     LOG(IndexedDB, "MemoryIndex::countForKeyRange");
101
102     if (!m_records)
103         return 0;
104
105     uint64_t count = 0;
106     IDBKeyRangeData range = inRange;
107     while (true) {
108         auto key = m_records->lowestKeyWithRecordInRange(range);
109         if (key.isNull())
110             break;
111
112         count += m_records->countForKey(key);
113
114         range.lowerKey = key;
115         range.lowerOpen = true;
116     }
117
118     return count;
119 }
120
121 IDBError MemoryIndex::putIndexKey(const IDBKeyData& valueKey, const IndexKey& indexKey)
122 {
123     LOG(IndexedDB, "MemoryIndex::provisionalPutIndexKey");
124
125     if (!m_records)
126         m_records = std::make_unique<IndexValueStore>(m_info.unique());
127
128     if (!m_info.multiEntry()) {
129         IDBKeyData key = indexKey.asOneKey();
130         return m_records->addRecord(key, valueKey);
131     }
132
133     Vector<IDBKeyData> keys = indexKey.multiEntry();
134
135     if (m_info.unique()) {
136         for (auto& key : keys) {
137             if (m_records->contains(key))
138                 return IDBError(IDBExceptionCode::ConstraintError);
139         }
140     }
141
142     for (auto& key : keys) {
143         auto error = m_records->addRecord(key, valueKey);
144         ASSERT_UNUSED(error, error.isNull());
145     }
146
147     return { };
148 }
149
150 void MemoryIndex::removeRecord(const IDBKeyData& valueKey, const IndexKey& indexKey)
151 {
152     LOG(IndexedDB, "MemoryIndex::removeRecord");
153
154     ASSERT(m_records);
155
156     if (!m_info.multiEntry()) {
157         IDBKeyData key = indexKey.asOneKey();
158         m_records->removeRecord(key, valueKey);
159         return;
160     }
161
162     Vector<IDBKeyData> keys = indexKey.multiEntry();
163     for (auto& key : keys)
164         m_records->removeRecord(key, valueKey);
165 }
166
167 void MemoryIndex::removeEntriesWithValueKey(const IDBKeyData& valueKey)
168 {
169     LOG(IndexedDB, "MemoryIndex::removeEntriesWithValueKey");
170
171     if (!m_records)
172         return;
173
174     m_records->removeEntriesWithValueKey(valueKey);
175 }
176
177 } // namespace IDBServer
178 } // namespace WebCore
179
180 #endif // ENABLE(INDEXED_DATABASE)