Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/toolkit/components/places/History.h
Line
Count
Source (jump to first uncovered line)
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_places_History_h_
8
#define mozilla_places_History_h_
9
10
#include "mozilla/IHistory.h"
11
#include "mozilla/MemoryReporting.h"
12
#include "mozilla/Move.h"
13
#include "mozilla/Mutex.h"
14
#include "mozIAsyncHistory.h"
15
#include "Database.h"
16
17
#include "mozilla/dom/Link.h"
18
#include "mozilla/ipc/URIParams.h"
19
#include "nsTHashtable.h"
20
#include "nsString.h"
21
#include "nsURIHashKey.h"
22
#include "nsTObserverArray.h"
23
#include "nsIMemoryReporter.h"
24
#include "nsIObserver.h"
25
#include "mozIStorageConnection.h"
26
27
namespace mozilla {
28
namespace places {
29
30
struct VisitData;
31
class ConcurrentStatementsHolder;
32
33
#define NS_HISTORYSERVICE_CID \
34
  {0x0937a705, 0x91a6, 0x417a, {0x82, 0x92, 0xb2, 0x2e, 0xb1, 0x0d, 0xa8, 0x6c}}
35
36
// Initial size of mRecentlyVisitedURIs.
37
#define RECENTLY_VISITED_URIS_SIZE 64
38
// Microseconds after which a visit can be expired from mRecentlyVisitedURIs.
39
// When an URI is reloaded we only take into account the first visit to it, and
40
// ignore any subsequent visits, if they happen before this time has elapsed.
41
// A commonly found case is to reload a page every 5 minutes, so we pick a time
42
// larger than that.
43
0
#define RECENTLY_VISITED_URIS_MAX_AGE 6 * 60 * PR_USEC_PER_SEC
44
// When notifying the main thread after inserting visits, we chunk the visits
45
// into medium-sized groups so that we can amortize the cost of the runnable
46
// without janking the main thread by expecting it to process hundreds at once.
47
0
#define NOTIFY_VISITS_CHUNK_SIZE 100
48
49
class History final : public IHistory
50
                    , public mozIAsyncHistory
51
                    , public nsIObserver
52
                    , public nsIMemoryReporter
53
{
54
public:
55
  NS_DECL_THREADSAFE_ISUPPORTS
56
  NS_DECL_IHISTORY
57
  NS_DECL_MOZIASYNCHISTORY
58
  NS_DECL_NSIOBSERVER
59
  NS_DECL_NSIMEMORYREPORTER
60
61
  History();
62
63
  /**
64
   * Obtains the statement to use to check if a URI is visited or not.
65
   */
66
  nsresult GetIsVisitedStatement(mozIStorageCompletionCallback* aCallback);
67
68
  /**
69
   * Adds an entry in moz_places with the data in aVisitData.
70
   *
71
   * @param aVisitData
72
   *        The visit data to use to populate a new row in moz_places.
73
   * @param aShouldNotifyFrecencyChanged
74
   *        Whether to dispatch OnFrecencyChanged notifications.
75
   *        Defaults to true. Set to false if you (the caller) are
76
   *        doing many inserts and will dispatch your own
77
   *        OnManyFrecenciesChanged notification.
78
   */
79
  nsresult InsertPlace(VisitData& aVisitData,
80
                       bool aShouldNotifyFrecencyChanged = true);
81
82
  /**
83
   * Updates an entry in moz_places with the data in aVisitData.
84
   *
85
   * @param aVisitData
86
   *        The visit data to use to update the existing row in moz_places.
87
   */
88
  nsresult UpdatePlace(const VisitData& aVisitData);
89
90
  /**
91
   * Loads information about the page into _place from moz_places.
92
   *
93
   * @param _place
94
   *        The VisitData for the place we need to know information about.
95
   * @param [out] _exists
96
   *        Whether or the page was recorded in moz_places, false otherwise.
97
   */
98
  nsresult FetchPageInfo(VisitData& _place, bool* _exists);
99
100
  /**
101
   * Get the number of bytes of memory this History object is using,
102
   * including sizeof(*this))
103
   */
104
  size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
105
106
  /**
107
   * Obtains a pointer to this service.
108
   */
109
  static History* GetService();
110
111
  /**
112
   * Used by the service manager only.
113
   */
114
  static already_AddRefed<History> GetSingleton();
115
116
  template<int N>
117
  already_AddRefed<mozIStorageStatement>
118
  GetStatement(const char (&aQuery)[N])
119
0
  {
120
0
    // May be invoked on both threads.
121
0
    const mozIStorageConnection* dbConn = GetConstDBConn();
122
0
    NS_ENSURE_TRUE(dbConn, nullptr);
123
0
    return mDB->GetStatement(aQuery);
124
0
  }
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<147>(char const (&) [147])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<146>(char const (&) [146])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<93>(char const (&) [93])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<71>(char const (&) [71])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<63>(char const (&) [63])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<168>(char const (&) [168])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<90>(char const (&) [90])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<106>(char const (&) [106])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<260>(char const (&) [260])
Unexecuted instantiation: already_AddRefed<mozIStorageStatement> mozilla::places::History::GetStatement<225>(char const (&) [225])
125
126
  already_AddRefed<mozIStorageStatement>
127
  GetStatement(const nsACString& aQuery)
128
0
  {
129
0
    // May be invoked on both threads.
130
0
    const mozIStorageConnection* dbConn = GetConstDBConn();
131
0
    NS_ENSURE_TRUE(dbConn, nullptr);
132
0
    return mDB->GetStatement(aQuery);
133
0
  }
134
135
0
  bool IsShuttingDown() const {
136
0
    return mShuttingDown;
137
0
  }
138
0
  Mutex& GetShutdownMutex() {
139
0
    return mShutdownMutex;
140
0
  }
141
142
  /**
143
   * Helper function to append a new URI to mRecentlyVisitedURIs. See
144
   * mRecentlyVisitedURIs.
145
   */
146
  void AppendToRecentlyVisitedURIs(nsIURI* aURI);
147
148
  void NotifyVisitedParent(const nsTArray<mozilla::ipc::URIParams>& aURIs);
149
private:
150
  virtual ~History();
151
152
  void InitMemoryReporter();
153
154
  /**
155
   * Obtains a read-write database connection, initializing the connection
156
   * if needed. Must be invoked on the main thread.
157
   */
158
  mozIStorageConnection* GetDBConn();
159
160
  /**
161
   * Obtains a read-write database connection, but won't try to initialize it.
162
   * May be invoked on both threads, but first one must invoke GetDBConn() on
163
   * the main-thread at least once.
164
   */
165
  const mozIStorageConnection* GetConstDBConn();
166
167
  /**
168
   * Mark all links for the given URI in the given document as visited. Used
169
   * within NotifyVisited.
170
   */
171
  void NotifyVisitedForDocument(nsIURI* aURI, nsIDocument* aDocument);
172
173
  /**
174
   * Dispatch a runnable for the document passed in which will call
175
   * NotifyVisitedForDocument with the correct URI and Document.
176
   */
177
  void DispatchNotifyVisited(nsIURI* aURI, nsIDocument* aDocument);
178
179
  /**
180
   * The database handle.  This is initialized lazily by the first call to
181
   * GetDBConn(), so never use it directly, or, if you really need, always
182
   * invoke GetDBConn() before.
183
   */
184
  RefPtr<mozilla::places::Database> mDB;
185
186
  RefPtr<ConcurrentStatementsHolder> mConcurrentStatementsHolder;
187
188
  /**
189
   * Remove any memory references to tasks and do not take on any more.
190
   */
191
  void Shutdown();
192
193
  static History* gService;
194
195
  // Ensures new tasks aren't started on destruction.
196
  bool mShuttingDown;
197
  // This mutex guards mShuttingDown. Code running in other threads that might
198
  // schedule tasks that use the database should grab it and check the value of
199
  // mShuttingDown. If we are already shutting down, the code must gracefully
200
  // avoid using the db. If we are not, the lock will prevent shutdown from
201
  // starting in an unexpected moment.
202
  Mutex mShutdownMutex;
203
204
  typedef nsTObserverArray<mozilla::dom::Link* > ObserverArray;
205
206
  class KeyClass : public nsURIHashKey
207
  {
208
  public:
209
    explicit KeyClass(const nsIURI* aURI)
210
    : nsURIHashKey(aURI)
211
0
    {
212
0
    }
213
    KeyClass(KeyClass&& aOther)
214
      : nsURIHashKey(std::move(aOther))
215
      , array(std::move(aOther.array))
216
      , mVisited(std::move(aOther.mVisited))
217
    {
218
      MOZ_ASSERT_UNREACHABLE("Do not call me!");
219
    }
220
    size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
221
0
    {
222
0
      return array.ShallowSizeOfExcludingThis(aMallocSizeOf);
223
0
    }
224
    ObserverArray array;
225
    bool mVisited = false;
226
  };
227
228
  nsTHashtable<KeyClass> mObservers;
229
230
  /**
231
   * mRecentlyVisitedURIs remembers URIs which have been recently added to
232
   * history, to avoid saving these locations repeatedly in a short period.
233
   */
234
  class RecentURIKey : public nsURIHashKey
235
  {
236
  public:
237
    explicit RecentURIKey(const nsIURI* aURI) : nsURIHashKey(aURI)
238
0
    {
239
0
    }
240
    RecentURIKey(RecentURIKey&& aOther) : nsURIHashKey(std::move(aOther))
241
    {
242
      MOZ_ASSERT_UNREACHABLE("Do not call me!");
243
    }
244
    MOZ_INIT_OUTSIDE_CTOR PRTime time;
245
  };
246
  nsTHashtable<RecentURIKey> mRecentlyVisitedURIs;
247
  /**
248
   * Whether aURI has been visited "recently".
249
   * See RECENTLY_VISITED_URIS_MAX_AGE.
250
   */
251
  bool IsRecentlyVisitedURI(nsIURI* aURI);
252
};
253
254
} // namespace places
255
} // namespace mozilla
256
257
#endif // mozilla_places_History_h_