1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef mozilla_dom_localstorage_LSWriteOptimizer_h
8 #define mozilla_dom_localstorage_LSWriteOptimizer_h
12 #include "mozilla/Assertions.h"
13 #include "mozilla/CheckedInt.h"
14 #include "mozilla/UniquePtr.h"
15 #include "nsClassHashtable.h"
16 #include "nsHashKeys.h"
17 #include "nsISupports.h"
18 #include "nsStringFwd.h"
19 #include "nsTArrayForwardDeclare.h"
21 namespace mozilla::dom
{
24 * Base class for coalescing manipulation queue.
26 class LSWriteOptimizerBase
{
27 class WriteInfoComparator
;
34 UniquePtr
<WriteInfo
> mTruncateInfo
;
35 nsClassHashtable
<nsStringHashKey
, WriteInfo
> mWriteInfos
;
36 CheckedUint64 mLastSerialNumber
;
42 LSWriteOptimizerBase() : mLastSerialNumber(0), mTotalDelta(0) {}
44 LSWriteOptimizerBase(LSWriteOptimizerBase
&& aWriteOptimizer
)
45 : mTruncateInfo(std::move(aWriteOptimizer
.mTruncateInfo
)) {
46 AssertIsOnOwningThread();
47 MOZ_ASSERT(&aWriteOptimizer
!= this);
49 mWriteInfos
.SwapElements(aWriteOptimizer
.mWriteInfos
);
50 mTotalDelta
= aWriteOptimizer
.mTotalDelta
;
51 aWriteOptimizer
.mTotalDelta
= 0;
54 void AssertIsOnOwningThread() const {
55 NS_ASSERT_OWNINGTHREAD(LSWriteOptimizerBase
);
58 void DeleteItem(const nsAString
& aKey
, int64_t aDelta
= 0);
60 void Truncate(int64_t aDelta
= 0);
62 bool HasWrites() const {
63 AssertIsOnOwningThread();
65 return mTruncateInfo
|| !mWriteInfos
.IsEmpty();
69 AssertIsOnOwningThread();
71 mTruncateInfo
= nullptr;
76 uint64_t NextSerialNumber() {
77 AssertIsOnOwningThread();
81 MOZ_ASSERT(mLastSerialNumber
.isValid());
83 return mLastSerialNumber
.value();
87 * This method can be used by derived classes to get a sorted list of write
88 * infos. Write infos are sorted by the serial number.
90 void GetSortedWriteInfos(nsTArray
<NotNull
<WriteInfo
*>>& aWriteInfos
);
94 * Base class for specific mutations.
96 class LSWriteOptimizerBase::WriteInfo
{
97 uint64_t mSerialNumber
;
100 WriteInfo(uint64_t aSerialNumber
) : mSerialNumber(aSerialNumber
) {}
102 virtual ~WriteInfo() = default;
104 uint64_t SerialNumber() const { return mSerialNumber
; }
106 enum Type
{ InsertItem
= 0, UpdateItem
, DeleteItem
, Truncate
};
108 virtual Type
GetType() const = 0;
111 class LSWriteOptimizerBase::DeleteItemInfo final
: public WriteInfo
{
115 DeleteItemInfo(uint64_t aSerialNumber
, const nsAString
& aKey
)
116 : WriteInfo(aSerialNumber
), mKey(aKey
) {}
118 const nsAString
& GetKey() const { return mKey
; }
121 Type
GetType() const override
{ return DeleteItem
; }
127 class LSWriteOptimizerBase::TruncateInfo final
: public WriteInfo
{
129 explicit TruncateInfo(uint64_t aSerialNumber
) : WriteInfo(aSerialNumber
) {}
132 Type
GetType() const override
{ return Truncate
; }
136 * Coalescing manipulation queue.
138 template <typename T
, typename U
= T
>
139 class LSWriteOptimizer
;
141 template <typename T
, typename U
>
142 class LSWriteOptimizer
: public LSWriteOptimizerBase
{
144 class InsertItemInfo
;
145 class UpdateItemInfo
;
148 void InsertItem(const nsAString
& aKey
, const T
& aValue
, int64_t aDelta
= 0);
150 void UpdateItem(const nsAString
& aKey
, const T
& aValue
, int64_t aDelta
= 0);
154 * Insert mutation (the key did not previously exist).
156 template <typename T
, typename U
>
157 class LSWriteOptimizer
<T
, U
>::InsertItemInfo
: public WriteInfo
{
162 InsertItemInfo(uint64_t aSerialNumber
, const nsAString
& aKey
, const T
& aValue
)
163 : WriteInfo(aSerialNumber
), mKey(aKey
), mValue(aValue
) {}
165 const nsAString
& GetKey() const { return mKey
; }
167 const T
& GetValue() const { return mValue
; }
170 WriteInfo::Type
GetType() const override
{ return InsertItem
; }
174 * Update mutation (the key already existed).
176 template <typename T
, typename U
>
177 class LSWriteOptimizer
<T
, U
>::UpdateItemInfo final
: public InsertItemInfo
{
178 bool mUpdateWithMove
;
181 UpdateItemInfo(uint64_t aSerialNumber
, const nsAString
& aKey
, const T
& aValue
,
182 bool aUpdateWithMove
)
183 : InsertItemInfo(aSerialNumber
, aKey
, aValue
),
184 mUpdateWithMove(aUpdateWithMove
) {}
186 bool UpdateWithMove() const { return mUpdateWithMove
; }
189 WriteInfo::Type
GetType() const override
{ return WriteInfo::UpdateItem
; }
192 } // namespace mozilla::dom
194 #endif // mozilla_dom_localstorage_LSWriteOptimizer_h