Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(473)

Side by Side Diff: components/reading_list/ios/reading_list_model_impl.cc

Issue 2525663002: Refactor Reading List Model to use URL as key. (Closed)
Patch Set: feedback Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/reading_list/ios/reading_list_model_impl.h" 5 #include "components/reading_list/ios/reading_list_model_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "components/prefs/pref_service.h" 11 #include "components/prefs/pref_service.h"
12 #include "components/reading_list/ios/reading_list_model_storage.h" 12 #include "components/reading_list/ios/reading_list_model_storage.h"
13 #include "components/reading_list/ios/reading_list_pref_names.h" 13 #include "components/reading_list/ios/reading_list_pref_names.h"
14 #include "url/gurl.h" 14 #include "url/gurl.h"
15 15
16 ReadingListModelImpl::Cache::Cache()
17 : read_entries(std::vector<GURL>()),
18 unread_entries(std::vector<GURL>()),
19 dirty(false) {}
20
21 ReadingListModelImpl::Cache::~Cache() {}
22
16 ReadingListModelImpl::ReadingListModelImpl() 23 ReadingListModelImpl::ReadingListModelImpl()
17 : ReadingListModelImpl(nullptr, nullptr) {} 24 : ReadingListModelImpl(nullptr, nullptr) {}
18 25
19 ReadingListModelImpl::ReadingListModelImpl( 26 ReadingListModelImpl::ReadingListModelImpl(
20 std::unique_ptr<ReadingListModelStorage> storage, 27 std::unique_ptr<ReadingListModelStorage> storage,
21 PrefService* pref_service) 28 PrefService* pref_service)
22 : pref_service_(pref_service), 29 : unread_entry_count_(0),
30 read_entry_count_(0),
31 cache_(base::MakeUnique<struct Cache>()),
32 pref_service_(pref_service),
23 has_unseen_(false), 33 has_unseen_(false),
24 loaded_(false), 34 loaded_(false),
25 weak_ptr_factory_(this) { 35 weak_ptr_factory_(this) {
26 DCHECK(CalledOnValidThread()); 36 DCHECK(CalledOnValidThread());
27 if (storage) { 37 if (storage) {
28 storage_layer_ = std::move(storage); 38 storage_layer_ = std::move(storage);
29 storage_layer_->SetReadingListModel(this, this); 39 storage_layer_->SetReadingListModel(this, this);
30 } else { 40 } else {
31 loaded_ = true; 41 loaded_ = true;
32 read_ = base::MakeUnique<ReadingListEntries>(); 42 entries_ = base::MakeUnique<ReadingListEntries>();
33 unread_ = base::MakeUnique<ReadingListEntries>(); 43 cache_->dirty = true;
34 } 44 }
35 has_unseen_ = GetPersistentHasUnseen(); 45 has_unseen_ = GetPersistentHasUnseen();
36 } 46 }
37 47
38 ReadingListModelImpl::~ReadingListModelImpl() {} 48 ReadingListModelImpl::~ReadingListModelImpl() {}
39 49
40 void ReadingListModelImpl::StoreLoaded( 50 void ReadingListModelImpl::StoreLoaded(
41 std::unique_ptr<ReadingListEntries> unread, 51 std::unique_ptr<ReadingListEntries> entries) {
42 std::unique_ptr<ReadingListEntries> read) {
43 DCHECK(CalledOnValidThread()); 52 DCHECK(CalledOnValidThread());
44 read_ = std::move(read); 53 entries_ = std::move(entries);
45 unread_ = std::move(unread); 54 cache_->dirty = true;
55 for (auto& iterator : *entries_) {
56 if (iterator.second.IsRead()) {
57 read_entry_count_++;
58 } else {
59 unread_entry_count_++;
60 }
61 }
62 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
46 loaded_ = true; 63 loaded_ = true;
47 SortEntries();
48 for (auto& observer : observers_) 64 for (auto& observer : observers_)
49 observer.ReadingListModelLoaded(this); 65 observer.ReadingListModelLoaded(this);
50 } 66 }
51 67
52 void ReadingListModelImpl::Shutdown() { 68 void ReadingListModelImpl::Shutdown() {
53 DCHECK(CalledOnValidThread()); 69 DCHECK(CalledOnValidThread());
54 for (auto& observer : observers_) 70 for (auto& observer : observers_)
55 observer.ReadingListModelBeingDeleted(this); 71 observer.ReadingListModelBeingDeleted(this);
56 loaded_ = false; 72 loaded_ = false;
57 } 73 }
58 74
59 bool ReadingListModelImpl::loaded() const { 75 bool ReadingListModelImpl::loaded() const {
60 DCHECK(CalledOnValidThread()); 76 DCHECK(CalledOnValidThread());
61 return loaded_; 77 return loaded_;
62 } 78 }
63 79
80 const ReadingListEntries::iterator ReadingListModelImpl::begin() const {
81 return entries_->begin();
82 }
83
84 const ReadingListEntries::iterator ReadingListModelImpl::end() const {
85 return entries_->end();
86 }
87
88 size_t ReadingListModelImpl::size() const {
89 DCHECK(CalledOnValidThread());
90 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
91 if (!loaded())
92 return 0;
93 return entries_->size();
94 }
95
64 size_t ReadingListModelImpl::unread_size() const { 96 size_t ReadingListModelImpl::unread_size() const {
65 DCHECK(CalledOnValidThread()); 97 DCHECK(CalledOnValidThread());
98 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
66 if (!loaded()) 99 if (!loaded())
67 return 0; 100 return 0;
68 return unread_->size(); 101 return unread_entry_count_;
69 } 102 }
70 103
71 size_t ReadingListModelImpl::read_size() const { 104 size_t ReadingListModelImpl::read_size() const {
72 DCHECK(CalledOnValidThread()); 105 DCHECK(CalledOnValidThread());
106 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
73 if (!loaded()) 107 if (!loaded())
74 return 0; 108 return 0;
75 return read_->size(); 109 return read_entry_count_;
76 } 110 }
77 111
78 bool ReadingListModelImpl::HasUnseenEntries() const { 112 bool ReadingListModelImpl::HasUnseenEntries() const {
79 DCHECK(CalledOnValidThread()); 113 DCHECK(CalledOnValidThread());
80 if (!loaded()) 114 if (!loaded())
81 return false; 115 return false;
82 return unread_size() && has_unseen_; 116 return unread_entry_count_ > 0 && has_unseen_;
83 } 117 }
84 118
85 void ReadingListModelImpl::ResetUnseenEntries() { 119 void ReadingListModelImpl::ResetUnseenEntries() {
86 DCHECK(CalledOnValidThread()); 120 DCHECK(CalledOnValidThread());
87 DCHECK(loaded()); 121 DCHECK(loaded());
88 has_unseen_ = false; 122 has_unseen_ = false;
89 if (!IsPerformingBatchUpdates()) 123 if (!IsPerformingBatchUpdates())
90 SetPersistentHasUnseen(false); 124 SetPersistentHasUnseen(false);
91 } 125 }
92 126
127 const ReadingListEntry* ReadingListModelImpl::GetEntryByURL(
128 const GURL& gurl) const {
129 DCHECK(CalledOnValidThread());
130 DCHECK(loaded());
131 return GetMutableEntryFromURL(gurl);
132 }
133
134 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex(
135 size_t index) const {
136 DCHECK(CalledOnValidThread());
137 DCHECK(loaded());
138 DCHECK(index < read_entry_count_);
139 if (cache_->dirty) {
140 RebuildIndex();
141 }
142 return *GetEntryByURL(cache_->read_entries[index]);
143 }
144
93 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( 145 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex(
94 size_t index) const { 146 size_t index) const {
95 DCHECK(CalledOnValidThread()); 147 DCHECK(CalledOnValidThread());
96 DCHECK(loaded()); 148 DCHECK(loaded());
97 return unread_->at(index); 149 DCHECK(index < unread_entry_count_);
150 if (cache_->dirty) {
151 RebuildIndex();
152 }
153 return *GetEntryByURL(cache_->unread_entries[index]);
98 } 154 }
99 155
100 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( 156 void ReadingListModelImpl::RebuildIndex() const {
101 size_t index) const {
102 DCHECK(CalledOnValidThread()); 157 DCHECK(CalledOnValidThread());
103 DCHECK(loaded()); 158 DCHECK(loaded());
104 return read_->at(index); 159 if (!cache_->dirty) {
105 } 160 return;
106 161 }
107 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( 162 cache_->dirty = false;
108 const GURL& gurl, 163 cache_->read_entries.clear();
109 bool* read) const { 164 cache_->unread_entries.clear();
110 DCHECK(CalledOnValidThread()); 165 for (auto& iterator : *entries_) {
111 DCHECK(loaded()); 166 if (iterator.second.IsRead()) {
112 return GetMutableEntryFromURL(gurl, read); 167 cache_->read_entries.push_back(iterator.first);
168 } else {
169 cache_->unread_entries.push_back(iterator.first);
170 }
171 }
172 DCHECK(read_entry_count_ == cache_->read_entries.size());
173 DCHECK(unread_entry_count_ == cache_->unread_entries.size());
174 std::sort(cache_->read_entries.begin(), cache_->read_entries.end(),
175 [this](const GURL& left_url, const GURL& right_url) {
176 return this->entries_->at(left_url).UpdateTime() >
jif-google 2016/11/28 16:28:21 Note: if this were not code that was going to be d
Olivier 2016/11/28 17:58:25 You cannot use operator[] on ReadingListEntries.
177 this->entries_->at(right_url).UpdateTime();
178 });
179 std::sort(cache_->unread_entries.begin(), cache_->unread_entries.end(),
180 [this](const GURL& left_url, const GURL& right_url) {
181 return this->entries_->at(left_url).UpdateTime() >
182 this->entries_->at(right_url).UpdateTime();
183 });
113 } 184 }
114 185
115 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL( 186 ReadingListEntry* ReadingListModelImpl::GetMutableEntryFromURL(
116 const GURL& gurl, 187 const GURL& url) const {
117 bool* read) const {
118 DCHECK(CalledOnValidThread()); 188 DCHECK(CalledOnValidThread());
119 DCHECK(loaded()); 189 DCHECK(loaded());
120 bool is_read; 190 auto iterator = entries_->find(url);
121 ReadingListEntry entry(gurl, std::string()); 191 if (iterator == entries_->end()) {
122 auto it = std::find(read_->begin(), read_->end(), entry); 192 return nullptr;
123 is_read = true;
124 if (it == read_->end()) {
125 it = std::find(unread_->begin(), unread_->end(), entry);
126 is_read = false;
127 if (it == unread_->end())
128 return nullptr;
129 } 193 }
130 if (read) { 194 return &(iterator->second);
131 *read = is_read;
132 }
133 return &(*it);
134 } 195 }
135 196
136 bool ReadingListModelImpl::CallbackEntryURL( 197 void ReadingListModelImpl::SyncAddEntry(
137 const GURL& url, 198 std::unique_ptr<ReadingListEntry> entry) {
138 base::Callback<void(const ReadingListEntry&)> callback) const {
139 DCHECK(CalledOnValidThread());
140 DCHECK(loaded());
141 const ReadingListEntry* entry = GetMutableEntryFromURL(url, nullptr);
142 if (entry) {
143 callback.Run(*entry);
144 return true;
145 }
146 return false;
147 }
148
149 void ReadingListModelImpl::MoveEntryFrom(ReadingListEntries* entries,
150 const ReadingListEntry& entry,
151 bool read) {
152 auto result = std::find(entries->begin(), entries->end(), entry);
153 DCHECK(result != entries->end());
154 int index = std::distance(entries->begin(), result);
155 for (auto& observer : observers_)
156 observer.ReadingListWillMoveEntry(this, index, read);
157 entries->erase(result);
158 }
159
160 void ReadingListModelImpl::SyncAddEntry(std::unique_ptr<ReadingListEntry> entry,
161 bool read) {
162 DCHECK(CalledOnValidThread()); 199 DCHECK(CalledOnValidThread());
163 DCHECK(loaded()); 200 DCHECK(loaded());
164 // entry must not already exist. 201 // entry must not already exist.
165 DCHECK(GetMutableEntryFromURL(entry->URL(), nullptr) == nullptr); 202 DCHECK(GetMutableEntryFromURL(entry->URL()) == nullptr);
166 if (read) { 203 for (auto& observer : observers_)
167 for (auto& observer : observers_) 204 observer.ReadingListWillAddEntry(this, *entry);
168 observer.ReadingListWillAddReadEntry(this, *entry); 205 if (entry->IsRead()) {
169 read_->insert(read_->begin(), std::move(*entry)); 206 read_entry_count_++;
170 } else { 207 } else {
171 for (auto& observer : observers_) 208 unread_entry_count_++;
172 observer.ReadingListWillAddUnreadEntry(this, *entry);
173 has_unseen_ = true;
174 SetPersistentHasUnseen(true); 209 SetPersistentHasUnseen(true);
175 unread_->insert(unread_->begin(), std::move(*entry)); 210 }
211 GURL url = entry->URL();
jif-google 2016/11/28 16:28:21 const GURL& url = entry->URL();
Olivier 2016/11/28 17:58:25 I need it for after the move, so I think I need a
jif 2016/11/28 18:15:31 oh wow, did not see that.
212 entries_->insert(std::make_pair(url, std::move(*entry)));
jif-google 2016/11/28 16:28:21 (*entries_)[url] = std::move(*entry); ?
Olivier 2016/11/28 17:58:25 You cannot use operator[] on entries.
jif 2016/11/28 18:15:31 Acknowledged.
213 cache_->dirty = true;
214 for (auto& observer : observers_) {
215 observer.ReadingListDidAddEntry(this, url);
216 observer.ReadingListDidApplyChanges(this);
217 }
218 }
219
220 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry(
221 std::unique_ptr<ReadingListEntry> entry) {
222 DCHECK(CalledOnValidThread());
223 DCHECK(loaded());
224 ReadingListEntry* existing_entry = GetMutableEntryFromURL(entry->URL());
225 DCHECK(existing_entry);
226 DCHECK(existing_entry->UpdateTime() < entry->UpdateTime());
227
228 GURL url = entry->URL();
jif-google 2016/11/28 16:28:21 const GURL& ?
Olivier 2016/11/28 17:58:25 I need it for after the move, so I think I need a
jif 2016/11/28 18:15:31 Acknowledged.
229
230 for (auto& observer : observers_)
231 observer.ReadingListWillMoveEntry(this, url);
232
233 if (existing_entry->IsRead()) {
234 read_entry_count_--;
235 } else {
236 unread_entry_count_--;
237 }
238 // Merge local data in new entry.
239 entry->MergeLocalStateFrom(*existing_entry);
240
241 entries_->find(url)->second = std::move(*entry);
jif-google 2016/11/28 16:28:21 (*entries_)[url] = std::move(*entry); ?
Olivier 2016/11/28 17:58:25 You cannot use operator[] on entries.
jif 2016/11/28 18:15:31 Acknowledged.
242 cache_->dirty = true;
243
244 existing_entry = GetMutableEntryFromURL(url);
245 if (existing_entry->IsRead()) {
246 read_entry_count_++;
247 } else {
248 unread_entry_count_++;
176 } 249 }
177 for (auto& observer : observers_) 250 for (auto& observer : observers_)
178 observer.ReadingListDidApplyChanges(this); 251 observer.ReadingListDidApplyChanges(this);
179 } 252 return existing_entry;
180
181 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry(
182 std::unique_ptr<ReadingListEntry> entry,
183 bool read) {
184 DCHECK(CalledOnValidThread());
185 DCHECK(loaded());
186 bool is_existing_entry_read;
187 ReadingListEntry* existing_entry =
188 GetMutableEntryFromURL(entry->URL(), &is_existing_entry_read);
189
190 DCHECK(existing_entry);
191 DCHECK(existing_entry->UpdateTime() < entry->UpdateTime());
192
193 // Merge local data in new entry.
194 entry->MergeLocalStateFrom(*existing_entry);
195
196 if (is_existing_entry_read) {
197 MoveEntryFrom(read_.get(), *existing_entry, true);
198 } else {
199 MoveEntryFrom(unread_.get(), *existing_entry, false);
200 }
201
202 ReadingListEntries::iterator added_iterator;
203 if (read) {
204 read_->push_back(std::move(*entry));
205 added_iterator = read_->end() - 1;
206 } else {
207 unread_->push_back(std::move(*entry));
208 added_iterator = unread_->end() - 1;
209 }
210 for (auto& observer : observers_)
211 observer.ReadingListDidApplyChanges(this);
212
213 ReadingListEntry& merged_entry = *added_iterator;
214 return &merged_entry;
215 } 253 }
216 254
217 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) { 255 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) {
218 RemoveEntryByURLImpl(url, true); 256 RemoveEntryByURLImpl(url, true);
219 } 257 }
220 258
221 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { 259 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) {
222 RemoveEntryByURLImpl(url, false); 260 RemoveEntryByURLImpl(url, false);
223 } 261 }
224 262
225 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, 263 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url,
226 bool from_sync) { 264 bool from_sync) {
227 DCHECK(CalledOnValidThread()); 265 DCHECK(CalledOnValidThread());
228 DCHECK(loaded()); 266 DCHECK(loaded());
229 const ReadingListEntry entry(url, std::string()); 267 const ReadingListEntry* entry = GetEntryByURL(url);
268 if (!entry)
269 return;
230 270
231 auto result = std::find(unread_->begin(), unread_->end(), entry); 271 for (auto& observer : observers_)
232 if (result != unread_->end()) { 272 observer.ReadingListWillRemoveEntry(this, url);
233 for (auto& observer : observers_)
234 observer.ReadingListWillRemoveUnreadEntry(
235 this, std::distance(unread_->begin(), result));
236 273
237 if (storage_layer_ && !from_sync) { 274 if (storage_layer_ && !from_sync) {
238 storage_layer_->RemoveEntry(*result); 275 storage_layer_->RemoveEntry(*entry);
239 }
240 unread_->erase(result);
241
242 for (auto& observer : observers_)
243 observer.ReadingListDidApplyChanges(this);
244 return;
245 } 276 }
246 277 if (entry->IsRead()) {
247 result = std::find(read_->begin(), read_->end(), entry); 278 read_entry_count_--;
248 if (result != read_->end()) { 279 } else {
249 for (auto& observer : observers_) 280 unread_entry_count_--;
250 observer.ReadingListWillRemoveReadEntry(
251 this, std::distance(read_->begin(), result));
252 if (storage_layer_ && !from_sync) {
253 storage_layer_->RemoveEntry(*result);
254 }
255 read_->erase(result);
256
257 for (auto& observer : observers_)
258 observer.ReadingListDidApplyChanges(this);
259 return;
260 } 281 }
282 entries_->erase(url);
283 cache_->dirty = true;
284 for (auto& observer : observers_)
285 observer.ReadingListDidApplyChanges(this);
261 } 286 }
262 287
263 const ReadingListEntry& ReadingListModelImpl::AddEntry( 288 const ReadingListEntry& ReadingListModelImpl::AddEntry(
264 const GURL& url, 289 const GURL& url,
265 const std::string& title) { 290 const std::string& title) {
266 DCHECK(CalledOnValidThread()); 291 DCHECK(CalledOnValidThread());
267 DCHECK(loaded()); 292 DCHECK(loaded());
268 RemoveEntryByURL(url); 293 RemoveEntryByURL(url);
269 294
270 std::string trimmedTitle(title); 295 std::string trimmedTitle(title);
271 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle); 296 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle);
272 297
273 ReadingListEntry entry(url, trimmedTitle); 298 ReadingListEntry entry(url, trimmedTitle);
274 for (auto& observer : observers_) 299 for (auto& observer : observers_)
275 observer.ReadingListWillAddUnreadEntry(this, entry); 300 observer.ReadingListWillAddEntry(this, entry);
276 has_unseen_ = true; 301 has_unseen_ = true;
277 SetPersistentHasUnseen(true); 302 SetPersistentHasUnseen(true);
303 entries_->insert(std::make_pair(url, std::move(entry)));
jif-google 2016/11/28 16:28:21 (*entries)[url] = std::move(entry);
Olivier 2016/11/28 17:58:25 You cannot use operator[] on entries.
jif 2016/11/28 18:15:31 Acknowledged.
304 unread_entry_count_++;
278 if (storage_layer_) { 305 if (storage_layer_) {
279 storage_layer_->SaveEntry(entry, false); 306 storage_layer_->SaveEntry(*GetEntryByURL(url));
280 } 307 }
281 unread_->insert(unread_->begin(), std::move(entry)); 308 cache_->dirty = true;
282 309
283 for (auto& observer : observers_) 310 for (auto& observer : observers_) {
311 observer.ReadingListDidAddEntry(this, url);
284 observer.ReadingListDidApplyChanges(this); 312 observer.ReadingListDidApplyChanges(this);
285 return *unread_->begin(); 313 }
314
315 return entries_->at(url);
jif-google 2016/11/28 16:28:21 return (*entries)[url];
Olivier 2016/11/28 17:58:25 You cannot use operator[] on entries.
jif 2016/11/28 18:15:31 Acknowledged.
316 }
317
318 void ReadingListModelImpl::MarkReadByURL(const GURL& url) {
319 return SetReadStatus(url, true);
286 } 320 }
287 321
288 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { 322 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) {
323 return SetReadStatus(url, false);
324 }
325
326 void ReadingListModelImpl::SetReadStatus(const GURL& url, bool read) {
289 DCHECK(CalledOnValidThread()); 327 DCHECK(CalledOnValidThread());
290 DCHECK(loaded()); 328 DCHECK(loaded());
291 ReadingListEntry entry(url, std::string()); 329 if (!entries_->count(url)) {
292 auto result = std::find(read_->begin(), read_->end(), entry);
293 if (result == read_->end())
294 return; 330 return;
295 331 }
332 ReadingListEntry& entry = entries_->at(url);
jif-google 2016/11/28 16:28:21 (*entries)[url]
Olivier 2016/11/28 17:58:25 You cannot use operator[] on entries.
jif 2016/11/28 18:15:31 Acknowledged.
333 if (entry.IsRead() == read) {
334 return;
335 }
296 for (ReadingListModelObserver& observer : observers_) { 336 for (ReadingListModelObserver& observer : observers_) {
297 observer.ReadingListWillMoveEntry( 337 observer.ReadingListWillMoveEntry(this, url);
298 this, std::distance(read_->begin(), result), true);
299 } 338 }
300 339 if (read) {
301 result->MarkEntryUpdated(); 340 read_entry_count_++;
341 unread_entry_count_--;
342 } else {
343 unread_entry_count_++;
344 read_entry_count_--;
345 }
346 entry.SetRead(read);
347 entry.MarkEntryUpdated();
348 cache_->dirty = true;
302 if (storage_layer_) { 349 if (storage_layer_) {
303 storage_layer_->SaveEntry(*result, false); 350 storage_layer_->SaveEntry(entry);
304 } 351 }
305
306 unread_->insert(unread_->begin(), std::move(*result));
307 read_->erase(result);
308
309 for (ReadingListModelObserver& observer : observers_) { 352 for (ReadingListModelObserver& observer : observers_) {
310 observer.ReadingListDidApplyChanges(this); 353 observer.ReadingListDidApplyChanges(this);
311 } 354 }
312 } 355 }
313 356
314 void ReadingListModelImpl::MarkReadByURL(const GURL& url) {
315 DCHECK(CalledOnValidThread());
316 DCHECK(loaded());
317 ReadingListEntry entry(url, std::string());
318 auto result = std::find(unread_->begin(), unread_->end(), entry);
319 if (result == unread_->end())
320 return;
321
322 for (auto& observer : observers_)
323 observer.ReadingListWillMoveEntry(
324 this, std::distance(unread_->begin(), result), false);
325
326 result->MarkEntryUpdated();
327 if (storage_layer_) {
328 storage_layer_->SaveEntry(*result, true);
329 }
330
331 read_->insert(read_->begin(), std::move(*result));
332 unread_->erase(result);
333
334 for (auto& observer : observers_)
335 observer.ReadingListDidApplyChanges(this);
336 }
337
338 void ReadingListModelImpl::SetEntryTitle(const GURL& url, 357 void ReadingListModelImpl::SetEntryTitle(const GURL& url,
339 const std::string& title) { 358 const std::string& title) {
340 DCHECK(CalledOnValidThread()); 359 DCHECK(CalledOnValidThread());
341 DCHECK(loaded()); 360 DCHECK(loaded());
342 const ReadingListEntry entry(url, std::string()); 361 if (!entries_->count(url)) {
jif-google 2016/11/28 16:28:21 How about we search the entry only once, as oppose
Olivier 2016/11/28 17:58:25 Done.
343 362 return;
344 auto result = std::find(unread_->begin(), unread_->end(), entry); 363 }
345 if (result != unread_->end()) { 364 ReadingListEntry& entry = entries_->at(url);
346 for (auto& observer : observers_) 365 if (entry.Title() == title) {
347 observer.ReadingListWillUpdateUnreadEntry(
348 this, std::distance(unread_->begin(), result));
349 result->SetTitle(title);
350
351 if (storage_layer_) {
352 storage_layer_->SaveEntry(*result, false);
353 }
354 for (auto& observer : observers_)
355 observer.ReadingListDidApplyChanges(this);
356 return; 366 return;
357 } 367 }
358 368
359 result = std::find(read_->begin(), read_->end(), entry); 369 for (ReadingListModelObserver& observer : observers_) {
360 if (result != read_->end()) { 370 observer.ReadingListWillUpdateEntry(this, url);
361 for (auto& observer : observers_) 371 }
362 observer.ReadingListWillUpdateReadEntry( 372 entry.SetTitle(title);
363 this, std::distance(read_->begin(), result)); 373 if (storage_layer_) {
364 result->SetTitle(title); 374 storage_layer_->SaveEntry(entry);
365 if (storage_layer_) { 375 }
366 storage_layer_->SaveEntry(*result, true); 376 for (ReadingListModelObserver& observer : observers_) {
367 } 377 observer.ReadingListDidApplyChanges(this);
368 for (auto& observer : observers_)
369 observer.ReadingListDidApplyChanges(this);
370 return;
371 } 378 }
372 } 379 }
373 380
374 void ReadingListModelImpl::SetEntryDistilledPath( 381 void ReadingListModelImpl::SetEntryDistilledPath(
375 const GURL& url, 382 const GURL& url,
376 const base::FilePath& distilled_path) { 383 const base::FilePath& distilled_path) {
377 DCHECK(CalledOnValidThread()); 384 DCHECK(CalledOnValidThread());
378 DCHECK(loaded()); 385 DCHECK(loaded());
379 const ReadingListEntry entry(url, std::string()); 386 if (!entries_->count(url)) {
jif-google 2016/11/28 16:28:21 same trick: only search for the entry once by usin
Olivier 2016/11/28 17:58:25 Done.
380 387 return;
381 auto result = std::find(unread_->begin(), unread_->end(), entry); 388 }
382 if (result != unread_->end()) { 389 ReadingListEntry& entry = entries_->at(url);
383 for (auto& observer : observers_) 390 if (entry.DistilledState() == ReadingListEntry::PROCESSED &&
384 observer.ReadingListWillUpdateUnreadEntry( 391 entry.DistilledPath() == distilled_path) {
385 this, std::distance(unread_->begin(), result));
386 result->SetDistilledPath(distilled_path);
387 if (storage_layer_) {
388 storage_layer_->SaveEntry(*result, false);
389 }
390 for (auto& observer : observers_)
391 observer.ReadingListDidApplyChanges(this);
392 return; 392 return;
393 } 393 }
394 394
395 result = std::find(read_->begin(), read_->end(), entry); 395 for (ReadingListModelObserver& observer : observers_) {
396 if (result != read_->end()) { 396 observer.ReadingListWillUpdateEntry(this, url);
397 for (auto& observer : observers_) 397 }
398 observer.ReadingListWillUpdateReadEntry( 398 entry.SetDistilledPath(distilled_path);
399 this, std::distance(read_->begin(), result)); 399 if (storage_layer_) {
400 result->SetDistilledPath(distilled_path); 400 storage_layer_->SaveEntry(entry);
401 if (storage_layer_) { 401 }
402 storage_layer_->SaveEntry(*result, true); 402 for (ReadingListModelObserver& observer : observers_) {
403 } 403 observer.ReadingListDidApplyChanges(this);
404 for (auto& observer : observers_)
405 observer.ReadingListDidApplyChanges(this);
406 return;
407 } 404 }
408 } 405 }
409 406
410 void ReadingListModelImpl::SetEntryDistilledState( 407 void ReadingListModelImpl::SetEntryDistilledState(
411 const GURL& url, 408 const GURL& url,
412 ReadingListEntry::DistillationState state) { 409 ReadingListEntry::DistillationState state) {
413 DCHECK(CalledOnValidThread()); 410 DCHECK(CalledOnValidThread());
414 DCHECK(loaded()); 411 DCHECK(loaded());
415 const ReadingListEntry entry(url, std::string()); 412 if (!entries_->count(url)) {
jif-google 2016/11/28 16:28:21 search for the entry once by using find().
Olivier 2016/11/28 17:58:25 Done.
416 413 return;
417 auto result = std::find(unread_->begin(), unread_->end(), entry); 414 }
418 if (result != unread_->end()) { 415 ReadingListEntry& entry = entries_->at(url);
419 for (auto& observer : observers_) 416 if (entry.DistilledState() == state) {
420 observer.ReadingListWillUpdateUnreadEntry(
421 this, std::distance(unread_->begin(), result));
422 result->SetDistilledState(state);
423 if (storage_layer_) {
424 storage_layer_->SaveEntry(*result, false);
425 }
426 for (auto& observer : observers_)
427 observer.ReadingListDidApplyChanges(this);
428 return; 417 return;
429 } 418 }
430 419
431 result = std::find(read_->begin(), read_->end(), entry); 420 for (ReadingListModelObserver& observer : observers_) {
432 if (result != read_->end()) { 421 observer.ReadingListWillUpdateEntry(this, url);
433 for (auto& observer : observers_)
434 observer.ReadingListWillUpdateReadEntry(
435 this, std::distance(read_->begin(), result));
436 result->SetDistilledState(state);
437 if (storage_layer_) {
438 storage_layer_->SaveEntry(*result, true);
439 }
440 for (auto& observer : observers_)
441 observer.ReadingListDidApplyChanges(this);
442 return;
443 } 422 }
444 }; 423 entry.SetDistilledState(state);
424 if (storage_layer_) {
425 storage_layer_->SaveEntry(entry);
426 }
427 for (ReadingListModelObserver& observer : observers_) {
428 observer.ReadingListDidApplyChanges(this);
429 }
430 }
445 431
446 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> 432 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate>
447 ReadingListModelImpl::CreateBatchToken() { 433 ReadingListModelImpl::CreateBatchToken() {
448 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>( 434 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>(
449 this); 435 this);
450 } 436 }
451 437
452 ReadingListModelImpl::ScopedReadingListBatchUpdate:: 438 ReadingListModelImpl::ScopedReadingListBatchUpdate::
453 ScopedReadingListBatchUpdate(ReadingListModelImpl* model) 439 ScopedReadingListBatchUpdate(ReadingListModelImpl* model)
454 : ReadingListModel::ScopedReadingListBatchUpdate:: 440 : ReadingListModel::ScopedReadingListBatchUpdate::
455 ScopedReadingListBatchUpdate(model) { 441 ScopedReadingListBatchUpdate(model) {
456 if (model->StorageLayer()) { 442 if (model->StorageLayer()) {
457 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); 443 storage_token_ = model->StorageLayer()->EnsureBatchCreated();
458 } 444 }
459 } 445 }
460 446
461 ReadingListModelImpl::ScopedReadingListBatchUpdate:: 447 ReadingListModelImpl::ScopedReadingListBatchUpdate::
462 ~ScopedReadingListBatchUpdate() { 448 ~ScopedReadingListBatchUpdate() {
463 storage_token_.reset(); 449 storage_token_.reset();
464 } 450 }
465 451
466 void ReadingListModelImpl::LeavingBatchUpdates() { 452 void ReadingListModelImpl::LeavingBatchUpdates() {
467 DCHECK(CalledOnValidThread()); 453 DCHECK(CalledOnValidThread());
468 if (storage_layer_) { 454 if (storage_layer_) {
469 SetPersistentHasUnseen(has_unseen_); 455 SetPersistentHasUnseen(has_unseen_);
470 SortEntries();
471 } 456 }
472 ReadingListModel::LeavingBatchUpdates(); 457 ReadingListModel::LeavingBatchUpdates();
473 } 458 }
474 459
475 void ReadingListModelImpl::EnteringBatchUpdates() { 460 void ReadingListModelImpl::EnteringBatchUpdates() {
476 DCHECK(CalledOnValidThread()); 461 DCHECK(CalledOnValidThread());
477 ReadingListModel::EnteringBatchUpdates(); 462 ReadingListModel::EnteringBatchUpdates();
478 } 463 }
479 464
480 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { 465 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) {
(...skipping 14 matching lines...) Expand all
495 reading_list::prefs::kReadingListHasUnseenEntries); 480 reading_list::prefs::kReadingListHasUnseenEntries);
496 } 481 }
497 482
498 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { 483 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() {
499 DCHECK(loaded()); 484 DCHECK(loaded());
500 if (!storage_layer_) 485 if (!storage_layer_)
501 return nullptr; 486 return nullptr;
502 return storage_layer_->GetModelTypeSyncBridge(); 487 return storage_layer_->GetModelTypeSyncBridge();
503 } 488 }
504 489
505 void ReadingListModelImpl::SortEntries() {
506 DCHECK(CalledOnValidThread());
507 DCHECK(loaded());
508 std::sort(read_->begin(), read_->end(),
509 ReadingListEntry::CompareEntryUpdateTime);
510 std::sort(unread_->begin(), unread_->end(),
511 ReadingListEntry::CompareEntryUpdateTime);
512 }
513
514 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() { 490 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() {
515 return storage_layer_.get(); 491 return storage_layer_.get();
516 } 492 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698