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

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: fix 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 size_t ReadingListModelImpl::size() const {
81 DCHECK(CalledOnValidThread());
82 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
83 if (!loaded())
84 return 0;
85 return entries_->size();
86 }
87
64 size_t ReadingListModelImpl::unread_size() const { 88 size_t ReadingListModelImpl::unread_size() const {
65 DCHECK(CalledOnValidThread()); 89 DCHECK(CalledOnValidThread());
90 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
66 if (!loaded()) 91 if (!loaded())
67 return 0; 92 return 0;
68 return unread_->size(); 93 return unread_entry_count_;
69 } 94 }
70 95
71 size_t ReadingListModelImpl::read_size() const { 96 size_t ReadingListModelImpl::read_size() const {
72 DCHECK(CalledOnValidThread()); 97 DCHECK(CalledOnValidThread());
98 DCHECK(read_entry_count_ + unread_entry_count_ == entries_->size());
73 if (!loaded()) 99 if (!loaded())
74 return 0; 100 return 0;
75 return read_->size(); 101 return read_entry_count_;
76 } 102 }
77 103
78 bool ReadingListModelImpl::HasUnseenEntries() const { 104 bool ReadingListModelImpl::HasUnseenEntries() const {
79 DCHECK(CalledOnValidThread()); 105 DCHECK(CalledOnValidThread());
80 if (!loaded()) 106 if (!loaded())
81 return false; 107 return false;
82 return unread_size() && has_unseen_; 108 return unread_entry_count_ > 0 && has_unseen_;
83 } 109 }
84 110
85 void ReadingListModelImpl::ResetUnseenEntries() { 111 void ReadingListModelImpl::ResetUnseenEntries() {
86 DCHECK(CalledOnValidThread()); 112 DCHECK(CalledOnValidThread());
87 DCHECK(loaded()); 113 DCHECK(loaded());
88 has_unseen_ = false; 114 has_unseen_ = false;
89 if (!IsPerformingBatchUpdates()) 115 if (!IsPerformingBatchUpdates())
90 SetPersistentHasUnseen(false); 116 SetPersistentHasUnseen(false);
91 } 117 }
92 118
119 const std::vector<GURL> ReadingListModelImpl::Keys() const {
120 std::vector<GURL> keys;
121 for (const auto& iterator : *entries_) {
122 keys.push_back(iterator.first);
123 }
124 return keys;
125 }
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() >
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();
212 entries_->insert(std::make_pair(url, std::move(*entry)));
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();
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);
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)));
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);
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 auto iterator = entries_->find(url);
292 auto result = std::find(read_->begin(), read_->end(), entry); 330 if (iterator == entries_->end()) {
293 if (result == read_->end())
294 return; 331 return;
295 332 }
333 ReadingListEntry& entry = iterator->second;
334 if (entry.IsRead() == read) {
335 return;
336 }
296 for (ReadingListModelObserver& observer : observers_) { 337 for (ReadingListModelObserver& observer : observers_) {
297 observer.ReadingListWillMoveEntry( 338 observer.ReadingListWillMoveEntry(this, url);
298 this, std::distance(read_->begin(), result), true);
299 } 339 }
300 340 if (read) {
301 result->MarkEntryUpdated(); 341 read_entry_count_++;
342 unread_entry_count_--;
343 } else {
344 unread_entry_count_++;
345 read_entry_count_--;
346 }
347 entry.SetRead(read);
348 entry.MarkEntryUpdated();
349 cache_->dirty = true;
302 if (storage_layer_) { 350 if (storage_layer_) {
303 storage_layer_->SaveEntry(*result, false); 351 storage_layer_->SaveEntry(entry);
304 } 352 }
305
306 unread_->insert(unread_->begin(), std::move(*result));
307 read_->erase(result);
308
309 for (ReadingListModelObserver& observer : observers_) { 353 for (ReadingListModelObserver& observer : observers_) {
310 observer.ReadingListDidApplyChanges(this); 354 observer.ReadingListDidApplyChanges(this);
311 } 355 }
312 } 356 }
313 357
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, 358 void ReadingListModelImpl::SetEntryTitle(const GURL& url,
339 const std::string& title) { 359 const std::string& title) {
340 DCHECK(CalledOnValidThread()); 360 DCHECK(CalledOnValidThread());
341 DCHECK(loaded()); 361 DCHECK(loaded());
342 const ReadingListEntry entry(url, std::string()); 362 auto iterator = entries_->find(url);
343 363 if (iterator == entries_->end()) {
344 auto result = std::find(unread_->begin(), unread_->end(), entry); 364 return;
345 if (result != unread_->end()) { 365 }
346 for (auto& observer : observers_) 366 ReadingListEntry& entry = iterator->second;
347 observer.ReadingListWillUpdateUnreadEntry( 367 if (entry.Title() == title) {
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; 368 return;
357 } 369 }
358 370
359 result = std::find(read_->begin(), read_->end(), entry); 371 for (ReadingListModelObserver& observer : observers_) {
360 if (result != read_->end()) { 372 observer.ReadingListWillUpdateEntry(this, url);
361 for (auto& observer : observers_) 373 }
362 observer.ReadingListWillUpdateReadEntry( 374 entry.SetTitle(title);
363 this, std::distance(read_->begin(), result)); 375 if (storage_layer_) {
364 result->SetTitle(title); 376 storage_layer_->SaveEntry(entry);
365 if (storage_layer_) { 377 }
366 storage_layer_->SaveEntry(*result, true); 378 for (ReadingListModelObserver& observer : observers_) {
367 } 379 observer.ReadingListDidApplyChanges(this);
368 for (auto& observer : observers_)
369 observer.ReadingListDidApplyChanges(this);
370 return;
371 } 380 }
372 } 381 }
373 382
374 void ReadingListModelImpl::SetEntryDistilledPath( 383 void ReadingListModelImpl::SetEntryDistilledPath(
375 const GURL& url, 384 const GURL& url,
376 const base::FilePath& distilled_path) { 385 const base::FilePath& distilled_path) {
377 DCHECK(CalledOnValidThread()); 386 DCHECK(CalledOnValidThread());
378 DCHECK(loaded()); 387 DCHECK(loaded());
379 const ReadingListEntry entry(url, std::string()); 388 auto iterator = entries_->find(url);
380 389 if (iterator == entries_->end()) {
381 auto result = std::find(unread_->begin(), unread_->end(), entry); 390 return;
382 if (result != unread_->end()) { 391 }
383 for (auto& observer : observers_) 392 ReadingListEntry& entry = iterator->second;
384 observer.ReadingListWillUpdateUnreadEntry( 393 if (entry.DistilledState() == ReadingListEntry::PROCESSED &&
385 this, std::distance(unread_->begin(), result)); 394 entry.DistilledPath() == distilled_path) {
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; 395 return;
393 } 396 }
394 397
395 result = std::find(read_->begin(), read_->end(), entry); 398 for (ReadingListModelObserver& observer : observers_) {
396 if (result != read_->end()) { 399 observer.ReadingListWillUpdateEntry(this, url);
397 for (auto& observer : observers_) 400 }
398 observer.ReadingListWillUpdateReadEntry( 401 entry.SetDistilledPath(distilled_path);
399 this, std::distance(read_->begin(), result)); 402 if (storage_layer_) {
400 result->SetDistilledPath(distilled_path); 403 storage_layer_->SaveEntry(entry);
401 if (storage_layer_) { 404 }
402 storage_layer_->SaveEntry(*result, true); 405 for (ReadingListModelObserver& observer : observers_) {
403 } 406 observer.ReadingListDidApplyChanges(this);
404 for (auto& observer : observers_)
405 observer.ReadingListDidApplyChanges(this);
406 return;
407 } 407 }
408 } 408 }
409 409
410 void ReadingListModelImpl::SetEntryDistilledState( 410 void ReadingListModelImpl::SetEntryDistilledState(
411 const GURL& url, 411 const GURL& url,
412 ReadingListEntry::DistillationState state) { 412 ReadingListEntry::DistillationState state) {
413 DCHECK(CalledOnValidThread()); 413 DCHECK(CalledOnValidThread());
414 DCHECK(loaded()); 414 DCHECK(loaded());
415 const ReadingListEntry entry(url, std::string()); 415 auto iterator = entries_->find(url);
416 416 if (iterator == entries_->end()) {
417 auto result = std::find(unread_->begin(), unread_->end(), entry); 417 return;
418 if (result != unread_->end()) { 418 }
419 for (auto& observer : observers_) 419 ReadingListEntry& entry = iterator->second;
420 observer.ReadingListWillUpdateUnreadEntry( 420 if (entry.DistilledState() == state) {
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; 421 return;
429 } 422 }
430 423
431 result = std::find(read_->begin(), read_->end(), entry); 424 for (ReadingListModelObserver& observer : observers_) {
432 if (result != read_->end()) { 425 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 } 426 }
444 }; 427 entry.SetDistilledState(state);
428 if (storage_layer_) {
429 storage_layer_->SaveEntry(entry);
430 }
431 for (ReadingListModelObserver& observer : observers_) {
432 observer.ReadingListDidApplyChanges(this);
433 }
434 }
445 435
446 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> 436 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate>
447 ReadingListModelImpl::CreateBatchToken() { 437 ReadingListModelImpl::CreateBatchToken() {
448 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>( 438 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>(
449 this); 439 this);
450 } 440 }
451 441
452 ReadingListModelImpl::ScopedReadingListBatchUpdate:: 442 ReadingListModelImpl::ScopedReadingListBatchUpdate::
453 ScopedReadingListBatchUpdate(ReadingListModelImpl* model) 443 ScopedReadingListBatchUpdate(ReadingListModelImpl* model)
454 : ReadingListModel::ScopedReadingListBatchUpdate:: 444 : ReadingListModel::ScopedReadingListBatchUpdate::
455 ScopedReadingListBatchUpdate(model) { 445 ScopedReadingListBatchUpdate(model) {
456 if (model->StorageLayer()) { 446 if (model->StorageLayer()) {
457 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); 447 storage_token_ = model->StorageLayer()->EnsureBatchCreated();
458 } 448 }
459 } 449 }
460 450
461 ReadingListModelImpl::ScopedReadingListBatchUpdate:: 451 ReadingListModelImpl::ScopedReadingListBatchUpdate::
462 ~ScopedReadingListBatchUpdate() { 452 ~ScopedReadingListBatchUpdate() {
463 storage_token_.reset(); 453 storage_token_.reset();
464 } 454 }
465 455
466 void ReadingListModelImpl::LeavingBatchUpdates() { 456 void ReadingListModelImpl::LeavingBatchUpdates() {
467 DCHECK(CalledOnValidThread()); 457 DCHECK(CalledOnValidThread());
468 if (storage_layer_) { 458 if (storage_layer_) {
469 SetPersistentHasUnseen(has_unseen_); 459 SetPersistentHasUnseen(has_unseen_);
470 SortEntries();
471 } 460 }
472 ReadingListModel::LeavingBatchUpdates(); 461 ReadingListModel::LeavingBatchUpdates();
473 } 462 }
474 463
475 void ReadingListModelImpl::EnteringBatchUpdates() { 464 void ReadingListModelImpl::EnteringBatchUpdates() {
476 DCHECK(CalledOnValidThread()); 465 DCHECK(CalledOnValidThread());
477 ReadingListModel::EnteringBatchUpdates(); 466 ReadingListModel::EnteringBatchUpdates();
478 } 467 }
479 468
480 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { 469 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) {
(...skipping 14 matching lines...) Expand all
495 reading_list::prefs::kReadingListHasUnseenEntries); 484 reading_list::prefs::kReadingListHasUnseenEntries);
496 } 485 }
497 486
498 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { 487 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() {
499 DCHECK(loaded()); 488 DCHECK(loaded());
500 if (!storage_layer_) 489 if (!storage_layer_)
501 return nullptr; 490 return nullptr;
502 return storage_layer_->GetModelTypeSyncBridge(); 491 return storage_layer_->GetModelTypeSyncBridge();
503 } 492 }
504 493
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() { 494 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() {
515 return storage_layer_.get(); 495 return storage_layer_.get();
516 } 496 }
OLDNEW
« no previous file with comments | « components/reading_list/ios/reading_list_model_impl.h ('k') | components/reading_list/ios/reading_list_model_observer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698