dom/localstorage/LSSnapshot.h
author Jan Varga <jan.varga@gmail.com>
Thu, 29 Nov 2018 21:49:10 +0100
changeset 505254 d5f866efde44d0e6d375dc7bcb24b86f21023103
parent 505249 bc288ab2655c2cf6d2404fd204b7afa1d67262d2
child 505257 4f699604c96059b4f198c2b2b8e12f3b3196d3cc
permissions -rw-r--r--
Bug 1286798 - Part 36: Allow snapshot initialization to a specific load state; r=asuth Before this patch, it was only possible to initialize a snapshot to the Partial state or AllOrderedItems state. Now there's a third state AllOrderedKeys. This improves performance by eliminating sync calls to parent process when we know nothing about a key in content process (in that case we have to use a sync call to the parent process to see if there's a value for it). With this patch we always try to send all keys to content when a snapshot is being initialized. For this to work efficiently, we cache the size of all keys. Having cached size of all keys also allows us to just iterate the mValues hashtable when the size of keys is bigger than snapshot prefill threshold (instead of iterating over the mKeys array and joining with mValues for each particular key). There's some additional cleanup in snapshot info construction and Datastore::SetItem/RemoveItem/Clear methods.

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef mozilla_dom_localstorage_LSSnapshot_h
#define mozilla_dom_localstorage_LSSnapshot_h

namespace mozilla {
namespace dom {

class LSDatabase;
class LSNotifyInfo;
class LSSnapshotChild;
class LSSnapshotInitInfo;
class LSWriteInfo;

class LSSnapshot final
  : public nsIRunnable
{
public:
  enum class LoadState
  {
    Initial,
    Partial,
    AllOrderedKeys,
    AllUnorderedItems,
    AllOrderedItems,
    EndGuard
  };

private:
  RefPtr<LSSnapshot> mSelfRef;

  RefPtr<LSDatabase> mDatabase;

  LSSnapshotChild* mActor;

  nsTHashtable<nsStringHashKey> mLoadedItems;
  nsTHashtable<nsStringHashKey> mUnknownItems;
  nsDataHashtable<nsStringHashKey, nsString> mValues;
  nsTArray<LSWriteInfo> mWriteInfos;

  uint32_t mInitLength;
  uint32_t mLength;
  int64_t mExactUsage;
  int64_t mPeakUsage;

  LoadState mLoadState;

  bool mExplicit;

#ifdef DEBUG
  bool mInitialized;
  bool mSentFinish;
#endif

public:
  explicit LSSnapshot(LSDatabase* aDatabase);

  void
  AssertIsOnOwningThread() const
  {
    NS_ASSERT_OWNINGTHREAD(LSSnapshot);
  }

  void
  SetActor(LSSnapshotChild* aActor);

  void
  ClearActor()
  {
    AssertIsOnOwningThread();
    MOZ_ASSERT(mActor);

    mActor = nullptr;
  }

  bool
  Explicit() const
  {
    return mExplicit;
  }

  nsresult
  Init(const LSSnapshotInitInfo& aInitInfo,
       bool aExplicit);

  nsresult
  GetLength(uint32_t* aResult);

  nsresult
  GetKey(uint32_t aIndex,
         nsAString& aResult);

  nsresult
  GetItem(const nsAString& aKey,
          nsAString& aResult);

  nsresult
  GetKeys(nsTArray<nsString>& aKeys);

  nsresult
  SetItem(const nsAString& aKey,
          const nsAString& aValue,
          LSNotifyInfo& aNotifyInfo);

  nsresult
  RemoveItem(const nsAString& aKey,
             LSNotifyInfo& aNotifyInfo);

  nsresult
  Clear(LSNotifyInfo& aNotifyInfo);

  nsresult
  Finish();

private:
  ~LSSnapshot();

  nsresult
  EnsureAllKeys();

  nsresult
  UpdateUsage(int64_t aDelta);

  NS_DECL_ISUPPORTS
  NS_DECL_NSIRUNNABLE
};

} // namespace dom
} // namespace mozilla

#endif // mozilla_dom_localstorage_LSSnapshot_h