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_LSSnapshot_h
8 #define mozilla_dom_localstorage_LSSnapshot_h
12 #include "ErrorList.h"
13 #include "mozilla/Assertions.h"
14 #include "mozilla/RefPtr.h"
15 #include "mozilla/UniquePtr.h"
17 #include "nsTHashMap.h"
18 #include "nsHashKeys.h"
19 #include "nsIRunnable.h"
20 #include "nsISupports.h"
21 #include "nsStringFwd.h"
22 #include "nsTArrayForwardDeclare.h"
23 #include "nsTHashSet.h"
27 namespace mozilla::dom
{
31 class LSSnapshotChild
;
32 class LSSnapshotInitInfo
;
33 class LSWriteAndNotifyInfo
;
34 class SnapshotWriteOptimizer
;
39 class LSSnapshot final
: public nsIRunnable
{
42 * The LoadState expresses what subset of information a snapshot has from the
43 * authoritative Datastore in the parent process. The initial snapshot is
44 * populated heuristically based on the size of the keys and size of the items
45 * (inclusive of the key value; item is key+value, not just value) of the
46 * entire datastore relative to the configured prefill limit (via pref
47 * "dom.storage.snapshot_prefill" exposed as gSnapshotPrefill in bytes).
49 * If there's less data than the limit, we send both keys and values and end
50 * up as AllOrderedItems. If there's enough room for all the keys but not
51 * all the values, we end up as AllOrderedKeys with as many values present as
52 * would fit. If there's not enough room for all the keys, then we end up as
53 * Partial with as many key-value pairs as will fit.
55 * The state AllUnorderedItems can only be reached by code getting items one
58 enum class LoadState
{
60 * Class constructed, Init(LSSnapshotInitInfo) has not been invoked yet.
64 * Some keys and their values are known.
68 * All the keys are known in order, but some values are unknown.
72 * All keys and their values are known, but in an arbitrary order.
76 * All keys and their values are known and are present in their canonical
77 * order. This is everything, and is the preferred case. The initial
78 * population will send this info when the size of all items is less than
79 * the prefill threshold.
81 * mValues will contain all keys and values, mLoadedItems and mUnknownItems
89 RefPtr
<LSSnapshot
> mSelfRef
;
91 RefPtr
<LSDatabase
> mDatabase
;
93 nsCOMPtr
<nsITimer
> mIdleTimer
;
95 LSSnapshotChild
* mActor
;
97 nsTHashSet
<nsString
> mLoadedItems
;
98 nsTHashSet
<nsString
> mUnknownItems
;
99 nsTHashMap
<nsStringHashKey
, nsString
> mValues
;
100 UniquePtr
<SnapshotWriteOptimizer
> mWriteOptimizer
;
101 UniquePtr
<nsTArray
<LSWriteAndNotifyInfo
>> mWriteAndNotifyInfos
;
103 uint32_t mInitLength
;
108 LoadState mLoadState
;
110 bool mHasOtherProcessDatabases
;
111 bool mHasOtherProcessObservers
;
113 bool mHasPendingStableStateCallback
;
114 bool mHasPendingIdleTimerCallback
;
123 explicit LSSnapshot(LSDatabase
* aDatabase
);
125 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSSnapshot
); }
127 void SetActor(LSSnapshotChild
* aActor
);
130 AssertIsOnOwningThread();
136 bool Explicit() const { return mExplicit
; }
138 nsresult
Init(const nsAString
& aKey
, const LSSnapshotInitInfo
& aInitInfo
,
141 nsresult
GetLength(uint32_t* aResult
);
143 nsresult
GetKey(uint32_t aIndex
, nsAString
& aResult
);
145 nsresult
GetItem(const nsAString
& aKey
, nsAString
& aResult
);
147 nsresult
GetKeys(nsTArray
<nsString
>& aKeys
);
149 nsresult
SetItem(const nsAString
& aKey
, const nsAString
& aValue
,
150 LSNotifyInfo
& aNotifyInfo
);
152 nsresult
RemoveItem(const nsAString
& aKey
, LSNotifyInfo
& aNotifyInfo
);
154 nsresult
Clear(LSNotifyInfo
& aNotifyInfo
);
158 nsresult
ExplicitCheckpoint();
160 nsresult
ExplicitEnd();
162 int64_t GetUsage() const;
167 void ScheduleStableStateCallback();
169 void MaybeScheduleStableStateCallback();
171 nsresult
GetItemInternal(const nsAString
& aKey
,
172 const Optional
<nsString
>& aValue
,
175 nsresult
EnsureAllKeys();
177 nsresult
UpdateUsage(int64_t aDelta
);
179 nsresult
Checkpoint(bool aSync
= false);
181 nsresult
Finish(bool aSync
= false);
183 void CancelIdleTimer();
185 static void IdleTimerCallback(nsITimer
* aTimer
, void* aClosure
);
191 } // namespace mozilla::dom
193 #endif // mozilla_dom_localstorage_LSSnapshot_h