LSSnapshot.h (5203B)
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/. */ 6 7 #ifndef mozilla_dom_localstorage_LSSnapshot_h 8 #define mozilla_dom_localstorage_LSSnapshot_h 9 10 #include <cstdint> 11 12 #include "ErrorList.h" 13 #include "mozilla/Assertions.h" 14 #include "mozilla/RefPtr.h" 15 #include "mozilla/UniquePtr.h" 16 #include "nsCOMPtr.h" 17 #include "nsHashKeys.h" 18 #include "nsIRunnable.h" 19 #include "nsISupports.h" 20 #include "nsStringFwd.h" 21 #include "nsTArrayForwardDeclare.h" 22 #include "nsTHashMap.h" 23 #include "nsTHashSet.h" 24 25 class nsITimer; 26 27 namespace mozilla::dom { 28 29 class LSDatabase; 30 class LSNotifyInfo; 31 class LSSnapshotChild; 32 class LSSnapshotInitInfo; 33 class LSWriteAndNotifyInfo; 34 class SnapshotWriteOptimizer; 35 36 template <typename> 37 class Optional; 38 39 class LSSnapshot final : public nsIRunnable { 40 public: 41 /** 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). 48 * 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. 54 * 55 * The state AllUnorderedItems can only be reached by code getting items one 56 * by one. 57 */ 58 enum class LoadState { 59 /** 60 * Class constructed, Init(LSSnapshotInitInfo) has not been invoked yet. 61 */ 62 Initial, 63 /** 64 * Some keys and their values are known. 65 */ 66 Partial, 67 /** 68 * All the keys are known in order, but some values are unknown. 69 */ 70 AllOrderedKeys, 71 /** 72 * All keys and their values are known, but in an arbitrary order. 73 */ 74 AllUnorderedItems, 75 /** 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. 80 * 81 * mValues will contain all keys and values, mLoadedItems and mUnknownItems 82 * are unused. 83 */ 84 AllOrderedItems, 85 EndGuard 86 }; 87 88 private: 89 RefPtr<LSSnapshot> mSelfRef; 90 91 RefPtr<LSDatabase> mDatabase; 92 93 nsCOMPtr<nsITimer> mIdleTimer; 94 95 LSSnapshotChild* mActor; 96 97 nsTHashSet<nsString> mLoadedItems; 98 nsTHashSet<nsString> mUnknownItems; 99 nsTHashMap<nsStringHashKey, nsString> mValues; 100 UniquePtr<SnapshotWriteOptimizer> mWriteOptimizer; 101 UniquePtr<nsTArray<LSWriteAndNotifyInfo>> mWriteAndNotifyInfos; 102 103 uint32_t mInitLength; 104 uint32_t mLength; 105 int64_t mUsage; 106 int64_t mPeakUsage; 107 108 LoadState mLoadState; 109 110 bool mHasOtherProcessDatabases; 111 bool mHasOtherProcessObservers; 112 bool mExplicit; 113 bool mHasPendingStableStateCallback; 114 bool mHasPendingIdleTimerCallback; 115 bool mDirty; 116 117 #ifdef DEBUG 118 bool mInitialized; 119 bool mSentFinish; 120 #endif 121 122 public: 123 explicit LSSnapshot(LSDatabase* aDatabase); 124 125 void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSSnapshot); } 126 127 void SetActor(LSSnapshotChild* aActor); 128 129 void ClearActor() { 130 AssertIsOnOwningThread(); 131 MOZ_ASSERT(mActor); 132 133 mActor = nullptr; 134 } 135 136 bool Explicit() const { return mExplicit; } 137 138 nsresult Init(const nsAString& aKey, const LSSnapshotInitInfo& aInitInfo, 139 bool aExplicit); 140 141 nsresult GetLength(uint32_t* aResult); 142 143 nsresult GetKey(uint32_t aIndex, nsAString& aResult); 144 145 nsresult GetItem(const nsAString& aKey, nsAString& aResult); 146 147 nsresult GetKeys(nsTArray<nsString>& aKeys); 148 149 nsresult SetItem(const nsAString& aKey, const nsAString& aValue, 150 LSNotifyInfo& aNotifyInfo); 151 152 nsresult RemoveItem(const nsAString& aKey, LSNotifyInfo& aNotifyInfo); 153 154 nsresult Clear(LSNotifyInfo& aNotifyInfo); 155 156 void MarkDirty(); 157 158 nsresult ExplicitCheckpoint(); 159 160 nsresult ExplicitEnd(); 161 162 int64_t GetUsage() const; 163 164 private: 165 ~LSSnapshot(); 166 167 void ScheduleStableStateCallback(); 168 169 void MaybeScheduleStableStateCallback(); 170 171 nsresult GetItemInternal(const nsAString& aKey, 172 const Optional<nsString>& aValue, 173 nsAString& aResult); 174 175 nsresult EnsureAllKeys(); 176 177 nsresult UpdateUsage(int64_t aDelta); 178 179 nsresult Checkpoint(bool aSync = false); 180 181 nsresult Finish(bool aSync = false); 182 183 void CancelIdleTimer(); 184 185 static void IdleTimerCallback(nsITimer* aTimer, void* aClosure); 186 187 NS_DECL_ISUPPORTS 188 NS_DECL_NSIRUNNABLE 189 }; 190 191 } // namespace mozilla::dom 192 193 #endif // mozilla_dom_localstorage_LSSnapshot_h