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

Side by Side Diff: ios/chrome/browser/reading_list/reading_list_model_impl.cc

Issue 2525663002: Refactor Reading List Model to use URL as key. (Closed)
Patch Set: format 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 "ios/chrome/browser/reading_list/reading_list_model_impl.h" 5 #include "ios/chrome/browser/reading_list/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 "ios/chrome/browser/reading_list/reading_list_model_storage.h" 12 #include "ios/chrome/browser/reading_list/reading_list_model_storage.h"
13 #include "ios/chrome/browser/reading_list/reading_list_pref_names.h" 13 #include "ios/chrome/browser/reading_list/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),
gambard 2016/11/23 12:11:07 I would have only kept the unread entry count. As
Olivier 2016/11/28 14:54:14 I will keep them at the moment, but I may remove o
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 unread_entry_count_ + read_entry_count_;
gambard 2016/11/23 12:11:07 entries_->size() is probably shorter and you are u
Olivier 2016/11/28 14:54:14 Done.
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_size() && 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
93 const ReadingListEntry& ReadingListModelImpl::GetUnreadEntryAtIndex( 119 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL(
gambard 2016/11/23 12:11:06 I am not sure this method makes sense. The order "
Olivier 2016/11/28 14:54:14 I guess this applies to GetEntryAt. Removed.
120 const GURL& gurl) const {
121 DCHECK(CalledOnValidThread());
122 DCHECK(loaded());
123 return GetMutableEntryFromURL(gurl);
124 }
125
126 const ReadingListEntry* ReadingListModelImpl::GetEntryAt(size_t index) const {
gambard 2016/11/23 12:11:07 Remove this method. You only need the old method f
Olivier 2016/11/28 14:54:14 Done.
127 DCHECK(CalledOnValidThread());
128 DCHECK(loaded());
129 if (index >= read_entry_count_ + unread_entry_count_) {
130 return nullptr;
131 }
132 if (cache_->dirty) {
133 RebuildIndex();
134 }
135 if (index < unread_entry_count_) {
136 return GetEntryFromURL(cache_->unread_entries[index]);
137 } else {
138 return GetEntryFromURL(cache_->read_entries[index - unread_entry_count_]);
139 }
140 }
141
142 const ReadingListEntry* ReadingListModelImpl::GetReadEntryAt(
gambard 2016/11/23 12:11:06 Same as above.
Olivier 2016/11/28 14:54:14 Done.
94 size_t index) const { 143 size_t index) const {
95 DCHECK(CalledOnValidThread()); 144 DCHECK(CalledOnValidThread());
96 DCHECK(loaded()); 145 DCHECK(loaded());
97 return unread_->at(index); 146 return GetEntryAt(unread_entry_count_ + index);
98 } 147 }
99 148
100 const ReadingListEntry& ReadingListModelImpl::GetReadEntryAtIndex( 149 const ReadingListEntry* ReadingListModelImpl::GetUnreadEntryAt(
101 size_t index) const { 150 size_t index) const {
102 DCHECK(CalledOnValidThread()); 151 DCHECK(CalledOnValidThread());
103 DCHECK(loaded()); 152 DCHECK(loaded());
104 return read_->at(index); 153 return GetEntryAt(index);
105 } 154 }
106 155
107 const ReadingListEntry* ReadingListModelImpl::GetEntryFromURL( 156 void ReadingListModelImpl::RebuildIndex() const {
108 const GURL& gurl,
109 bool* read) const {
110 DCHECK(CalledOnValidThread()); 157 DCHECK(CalledOnValidThread());
111 DCHECK(loaded()); 158 DCHECK(loaded());
112 return GetMutableEntryFromURL(gurl, read); 159 if (!cache_->dirty) {
160 return;
161 }
162 cache_->dirty = false;
163 cache_->read_entries.clear();
164 cache_->unread_entries.clear();
165 for (auto& iterator : *entries_) {
166 if (iterator.second.IsRead()) {
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& gurl) const {
117 bool* read) const {
118 DCHECK(CalledOnValidThread()); 188 DCHECK(CalledOnValidThread());
119 DCHECK(loaded()); 189 DCHECK(loaded());
120 bool is_read; 190 if (!entries_->count(gurl))
jif-google 2016/11/22 18:21:45 instead of calling |->count| and |->at|, just do a
Olivier 2016/11/28 14:54:14 Done.
121 ReadingListEntry entry(gurl, std::string()); 191 return nullptr;
122 auto it = std::find(read_->begin(), read_->end(), entry); 192 return &entries_->at(gurl);
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 }
130 if (read) {
131 *read = is_read;
132 }
133 return &(*it);
134 } 193 }
135 194
136 bool ReadingListModelImpl::CallbackEntryURL( 195 bool ReadingListModelImpl::CallbackEntryURL(
137 const GURL& url, 196 const GURL& url,
138 base::Callback<void(const ReadingListEntry&)> callback) const { 197 base::Callback<void(const ReadingListEntry&)> callback) const {
139 DCHECK(CalledOnValidThread()); 198 DCHECK(CalledOnValidThread());
140 DCHECK(loaded()); 199 DCHECK(loaded());
141 const ReadingListEntry* entry = GetMutableEntryFromURL(url, nullptr); 200 const ReadingListEntry* entry = GetMutableEntryFromURL(url);
142 if (entry) { 201 if (entry) {
143 callback.Run(*entry); 202 callback.Run(*entry);
144 return true; 203 return true;
145 } 204 }
146 return false; 205 return false;
147 } 206 }
148 207
149 void ReadingListModelImpl::MoveEntryFrom(ReadingListEntries* entries, 208 void ReadingListModelImpl::SyncAddEntry(
150 const ReadingListEntry& entry, 209 std::unique_ptr<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()); 210 DCHECK(CalledOnValidThread());
163 DCHECK(loaded()); 211 DCHECK(loaded());
164 // entry must not already exist. 212 // entry must not already exist.
165 DCHECK(GetMutableEntryFromURL(entry->URL(), nullptr) == nullptr); 213 DCHECK(GetMutableEntryFromURL(entry->URL()) == nullptr);
166 if (read) { 214 for (auto& observer : observers_)
167 for (auto& observer : observers_) 215 observer.ReadingListWillAddEntry(this, *entry);
168 observer.ReadingListWillAddReadEntry(this, *entry); 216 if (entry->IsRead()) {
169 read_->insert(read_->begin(), std::move(*entry)); 217 read_entry_count_++;
170 } else { 218 } else {
171 for (auto& observer : observers_) 219 unread_entry_count_++;
172 observer.ReadingListWillAddUnreadEntry(this, *entry);
173 has_unseen_ = true;
174 SetPersistentHasUnseen(true); 220 SetPersistentHasUnseen(true);
175 unread_->insert(unread_->begin(), std::move(*entry));
176 } 221 }
222 entries_->insert(std::make_pair(entry->URL(), std::move(*entry)));
jif-google 2016/11/22 18:21:45 this is pretty much: some_func(a, std::move(a)); y
Olivier 2016/11/28 14:54:14 Done. You cannot use operator[] as there is no def
223 cache_->dirty = true;
177 for (auto& observer : observers_) 224 for (auto& observer : observers_)
178 observer.ReadingListDidApplyChanges(this); 225 observer.ReadingListDidApplyChanges(this);
179 } 226 }
180 227
181 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry( 228 ReadingListEntry* ReadingListModelImpl::SyncMergeEntry(
182 std::unique_ptr<ReadingListEntry> entry, 229 std::unique_ptr<ReadingListEntry> entry) {
183 bool read) {
184 DCHECK(CalledOnValidThread()); 230 DCHECK(CalledOnValidThread());
185 DCHECK(loaded()); 231 DCHECK(loaded());
186 bool is_existing_entry_read; 232 ReadingListEntry* existing_entry = GetMutableEntryFromURL(entry->URL());
187 ReadingListEntry* existing_entry =
188 GetMutableEntryFromURL(entry->URL(), &is_existing_entry_read);
189
190 DCHECK(existing_entry); 233 DCHECK(existing_entry);
191 DCHECK(existing_entry->UpdateTime() < entry->UpdateTime()); 234 DCHECK(existing_entry->UpdateTime() < entry->UpdateTime());
192 235
236 GURL url = entry->URL();
jif-google 2016/11/22 18:21:45 const GURL & url = ...
Olivier 2016/11/28 14:54:14 I need the url adter the std::move, so I make a co
237
238 for (auto& observer : observers_)
239 observer.ReadingListWillMoveEntry(this, url);
240
241 if (existing_entry->IsRead()) {
242 read_entry_count_--;
243 } else {
244 unread_entry_count_--;
245 }
193 // Merge local data in new entry. 246 // Merge local data in new entry.
194 entry->MergeLocalStateFrom(*existing_entry); 247 entry->MergeLocalStateFrom(*existing_entry);
195 248
196 if (is_existing_entry_read) { 249 entries_->find(url)->second = std::move(*entry);
197 MoveEntryFrom(read_.get(), *existing_entry, true); 250 cache_->dirty = true;
251
252 existing_entry = GetMutableEntryFromURL(entry->URL());
253 if (existing_entry->IsRead()) {
254 read_entry_count_++;
198 } else { 255 } else {
199 MoveEntryFrom(unread_.get(), *existing_entry, false); 256 unread_entry_count_++;
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 } 257 }
210 for (auto& observer : observers_) 258 for (auto& observer : observers_)
211 observer.ReadingListDidApplyChanges(this); 259 observer.ReadingListDidApplyChanges(this);
212 260 return existing_entry;
213 ReadingListEntry& merged_entry = *added_iterator;
214 return &merged_entry;
215 } 261 }
216 262
217 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) { 263 void ReadingListModelImpl::SyncRemoveEntry(const GURL& url) {
218 RemoveEntryByURLImpl(url, true); 264 RemoveEntryByURLImpl(url, true);
219 } 265 }
220 266
221 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) { 267 void ReadingListModelImpl::RemoveEntryByURL(const GURL& url) {
222 RemoveEntryByURLImpl(url, false); 268 RemoveEntryByURLImpl(url, false);
223 } 269 }
224 270
225 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url, 271 void ReadingListModelImpl::RemoveEntryByURLImpl(const GURL& url,
226 bool from_sync) { 272 bool from_sync) {
227 DCHECK(CalledOnValidThread()); 273 DCHECK(CalledOnValidThread());
228 DCHECK(loaded()); 274 DCHECK(loaded());
229 const ReadingListEntry entry(url, std::string()); 275 if (!entries_->count(url))
276 return;
230 277
231 auto result = std::find(unread_->begin(), unread_->end(), entry); 278 for (auto& observer : observers_)
232 if (result != unread_->end()) { 279 observer.ReadingListWillRemoveEntry(this, url);
233 for (auto& observer : observers_) 280 const ReadingListEntry* entry = GetEntryFromURL(url);
234 observer.ReadingListWillRemoveUnreadEntry( 281 if (storage_layer_ && !from_sync) {
235 this, std::distance(unread_->begin(), result)); 282 storage_layer_->RemoveEntry(entry);
236
237 if (storage_layer_ && !from_sync) {
238 storage_layer_->RemoveEntry(*result);
239 }
240 unread_->erase(result);
241
242 for (auto& observer : observers_)
243 observer.ReadingListDidApplyChanges(this);
244 return;
245 } 283 }
246 284 if (entry->IsRead()) {
247 result = std::find(read_->begin(), read_->end(), entry); 285 read_entry_count_--;
248 if (result != read_->end()) { 286 } else {
249 for (auto& observer : observers_) 287 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 } 288 }
289 entries_->erase(url);
290 cache_->dirty = true;
291 for (auto& observer : observers_)
292 observer.ReadingListDidApplyChanges(this);
261 } 293 }
262 294
263 const ReadingListEntry& ReadingListModelImpl::AddEntry( 295 const ReadingListEntry& ReadingListModelImpl::AddEntry(
264 const GURL& url, 296 const GURL& url,
265 const std::string& title) { 297 const std::string& title) {
266 DCHECK(CalledOnValidThread()); 298 DCHECK(CalledOnValidThread());
267 DCHECK(loaded()); 299 DCHECK(loaded());
268 RemoveEntryByURL(url); 300 RemoveEntryByURL(url);
jif-google 2016/11/22 18:21:45 Wouldn't it make more sense to call "willUpdateEnt
Olivier 2016/11/28 14:54:14 The current workflow is to remove the entry, then
269 301
270 std::string trimmedTitle(title); 302 std::string trimmedTitle(title);
271 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle); 303 base::TrimWhitespaceASCII(trimmedTitle, base::TRIM_ALL, &trimmedTitle);
272 304
273 ReadingListEntry entry(url, trimmedTitle); 305 ReadingListEntry entry(url, trimmedTitle);
274 for (auto& observer : observers_) 306 for (auto& observer : observers_)
275 observer.ReadingListWillAddUnreadEntry(this, entry); 307 observer.ReadingListWillAddEntry(this, entry);
276 has_unseen_ = true; 308 has_unseen_ = true;
277 SetPersistentHasUnseen(true); 309 SetPersistentHasUnseen(true);
310 entries_->insert(std::make_pair(url, std::move(entry)));
311 unread_entry_count_++;
278 if (storage_layer_) { 312 if (storage_layer_) {
279 storage_layer_->SaveEntry(entry, false); 313 storage_layer_->SaveEntry(GetEntryFromURL(url));
280 } 314 }
281 unread_->insert(unread_->begin(), std::move(entry)); 315 cache_->dirty = true;
282 316
283 for (auto& observer : observers_) 317 for (auto& observer : observers_)
284 observer.ReadingListDidApplyChanges(this); 318 observer.ReadingListDidApplyChanges(this);
285 return *unread_->begin(); 319 return entries_->at(url);
286 } 320 }
287 321
288 void ReadingListModelImpl::MarkUnreadByURL(const GURL& url) { 322 void ReadingListModelImpl::SetReadStatus(const GURL& url, bool read) {
289 DCHECK(CalledOnValidThread()); 323 DCHECK(CalledOnValidThread());
290 DCHECK(loaded()); 324 DCHECK(loaded());
291 ReadingListEntry entry(url, std::string()); 325 if (!entries_->count(url)) {
292 auto result = std::find(read_->begin(), read_->end(), entry);
293 if (result == read_->end())
294 return; 326 return;
295 327 }
328 ReadingListEntry& entry = entries_->at(url);
329 if (entry.IsRead() == read) {
330 return;
331 }
296 for (ReadingListModelObserver& observer : observers_) { 332 for (ReadingListModelObserver& observer : observers_) {
297 observer.ReadingListWillMoveEntry( 333 observer.ReadingListWillMoveEntry(this, url);
298 this, std::distance(read_->begin(), result), true);
299 } 334 }
300 335 if (read) {
301 result->MarkEntryUpdated(); 336 read_entry_count_++;
337 unread_entry_count_--;
338 } else {
339 unread_entry_count_++;
340 read_entry_count_--;
341 }
342 entry.SetRead(read);
343 entry.MarkEntryUpdated();
344 cache_->dirty = true;
302 if (storage_layer_) { 345 if (storage_layer_) {
303 storage_layer_->SaveEntry(*result, false); 346 storage_layer_->SaveEntry(GetEntryFromURL(url));
304 } 347 }
305
306 unread_->insert(unread_->begin(), std::move(*result));
307 read_->erase(result);
308
309 for (ReadingListModelObserver& observer : observers_) { 348 for (ReadingListModelObserver& observer : observers_) {
310 observer.ReadingListDidApplyChanges(this); 349 observer.ReadingListDidApplyChanges(this);
311 } 350 }
312 } 351 }
313 352
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, 353 void ReadingListModelImpl::SetEntryTitle(const GURL& url,
339 const std::string& title) { 354 const std::string& title) {
340 DCHECK(CalledOnValidThread()); 355 DCHECK(CalledOnValidThread());
341 DCHECK(loaded()); 356 DCHECK(loaded());
342 const ReadingListEntry entry(url, std::string()); 357 if (!entries_->count(url)) {
343 358 return;
344 auto result = std::find(unread_->begin(), unread_->end(), entry); 359 }
345 if (result != unread_->end()) { 360 ReadingListEntry& entry = entries_->at(url);
346 for (auto& observer : observers_) 361 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; 362 return;
357 } 363 }
358 364
359 result = std::find(read_->begin(), read_->end(), entry); 365 for (ReadingListModelObserver& observer : observers_) {
360 if (result != read_->end()) { 366 observer.ReadingListWillUpdateEntry(this, url);
361 for (auto& observer : observers_) 367 }
362 observer.ReadingListWillUpdateReadEntry( 368 entry.SetTitle(title);
363 this, std::distance(read_->begin(), result)); 369 if (storage_layer_) {
364 result->SetTitle(title); 370 storage_layer_->SaveEntry(GetEntryFromURL(url));
365 if (storage_layer_) { 371 }
366 storage_layer_->SaveEntry(*result, true); 372 for (ReadingListModelObserver& observer : observers_) {
367 } 373 observer.ReadingListDidApplyChanges(this);
368 for (auto& observer : observers_)
369 observer.ReadingListDidApplyChanges(this);
370 return;
371 } 374 }
372 } 375 }
373 376
374 void ReadingListModelImpl::SetEntryDistilledPath( 377 void ReadingListModelImpl::SetEntryDistilledPath(
375 const GURL& url, 378 const GURL& url,
376 const base::FilePath& distilled_path) { 379 const base::FilePath& distilled_path) {
377 DCHECK(CalledOnValidThread()); 380 DCHECK(CalledOnValidThread());
378 DCHECK(loaded()); 381 DCHECK(loaded());
379 const ReadingListEntry entry(url, std::string()); 382 if (!entries_->count(url)) {
380 383 return;
381 auto result = std::find(unread_->begin(), unread_->end(), entry); 384 }
382 if (result != unread_->end()) { 385 ReadingListEntry& entry = entries_->at(url);
383 for (auto& observer : observers_) 386 if (entry.DistilledState() == ReadingListEntry::PROCESSED &&
384 observer.ReadingListWillUpdateUnreadEntry( 387 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; 388 return;
393 } 389 }
394 390
395 result = std::find(read_->begin(), read_->end(), entry); 391 for (ReadingListModelObserver& observer : observers_) {
396 if (result != read_->end()) { 392 observer.ReadingListWillUpdateEntry(this, url);
397 for (auto& observer : observers_) 393 }
398 observer.ReadingListWillUpdateReadEntry( 394 entry.SetDistilledPath(distilled_path);
399 this, std::distance(read_->begin(), result)); 395 if (storage_layer_) {
400 result->SetDistilledPath(distilled_path); 396 storage_layer_->SaveEntry(GetEntryFromURL(url));
401 if (storage_layer_) { 397 }
402 storage_layer_->SaveEntry(*result, true); 398 for (ReadingListModelObserver& observer : observers_) {
403 } 399 observer.ReadingListDidApplyChanges(this);
404 for (auto& observer : observers_)
405 observer.ReadingListDidApplyChanges(this);
406 return;
407 } 400 }
408 } 401 }
409 402
410 void ReadingListModelImpl::SetEntryDistilledState( 403 void ReadingListModelImpl::SetEntryDistilledState(
411 const GURL& url, 404 const GURL& url,
412 ReadingListEntry::DistillationState state) { 405 ReadingListEntry::DistillationState state) {
413 DCHECK(CalledOnValidThread()); 406 DCHECK(CalledOnValidThread());
414 DCHECK(loaded()); 407 DCHECK(loaded());
415 const ReadingListEntry entry(url, std::string()); 408 if (!entries_->count(url)) {
416 409 return;
417 auto result = std::find(unread_->begin(), unread_->end(), entry); 410 }
418 if (result != unread_->end()) { 411 ReadingListEntry& entry = entries_->at(url);
419 for (auto& observer : observers_) 412 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; 413 return;
429 } 414 }
430 415
431 result = std::find(read_->begin(), read_->end(), entry); 416 for (ReadingListModelObserver& observer : observers_) {
432 if (result != read_->end()) { 417 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 } 418 }
444 }; 419 entry.SetDistilledState(state);
420 if (storage_layer_) {
421 storage_layer_->SaveEntry(GetEntryFromURL(url));
422 }
423 for (ReadingListModelObserver& observer : observers_) {
424 observer.ReadingListDidApplyChanges(this);
425 }
426 }
445 427
446 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate> 428 std::unique_ptr<ReadingListModel::ScopedReadingListBatchUpdate>
447 ReadingListModelImpl::CreateBatchToken() { 429 ReadingListModelImpl::CreateBatchToken() {
448 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>( 430 return base::MakeUnique<ReadingListModelImpl::ScopedReadingListBatchUpdate>(
449 this); 431 this);
450 } 432 }
451 433
452 ReadingListModelImpl::ScopedReadingListBatchUpdate:: 434 ReadingListModelImpl::ScopedReadingListBatchUpdate::
453 ScopedReadingListBatchUpdate(ReadingListModelImpl* model) 435 ScopedReadingListBatchUpdate(ReadingListModelImpl* model)
454 : ReadingListModel::ScopedReadingListBatchUpdate:: 436 : ReadingListModel::ScopedReadingListBatchUpdate::
455 ScopedReadingListBatchUpdate(model) { 437 ScopedReadingListBatchUpdate(model) {
456 if (model->StorageLayer()) { 438 if (model->StorageLayer()) {
457 storage_token_ = model->StorageLayer()->EnsureBatchCreated(); 439 storage_token_ = model->StorageLayer()->EnsureBatchCreated();
458 } 440 }
459 } 441 }
460 442
461 ReadingListModelImpl::ScopedReadingListBatchUpdate:: 443 ReadingListModelImpl::ScopedReadingListBatchUpdate::
462 ~ScopedReadingListBatchUpdate() { 444 ~ScopedReadingListBatchUpdate() {
463 storage_token_.reset(); 445 storage_token_.reset();
464 } 446 }
465 447
466 void ReadingListModelImpl::LeavingBatchUpdates() { 448 void ReadingListModelImpl::LeavingBatchUpdates() {
467 DCHECK(CalledOnValidThread()); 449 DCHECK(CalledOnValidThread());
468 if (storage_layer_) { 450 if (storage_layer_) {
469 SetPersistentHasUnseen(has_unseen_); 451 SetPersistentHasUnseen(has_unseen_);
470 SortEntries();
471 } 452 }
472 ReadingListModel::LeavingBatchUpdates(); 453 ReadingListModel::LeavingBatchUpdates();
473 } 454 }
474 455
475 void ReadingListModelImpl::EnteringBatchUpdates() { 456 void ReadingListModelImpl::EnteringBatchUpdates() {
476 DCHECK(CalledOnValidThread()); 457 DCHECK(CalledOnValidThread());
477 ReadingListModel::EnteringBatchUpdates(); 458 ReadingListModel::EnteringBatchUpdates();
478 } 459 }
479 460
480 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) { 461 void ReadingListModelImpl::SetPersistentHasUnseen(bool has_unseen) {
(...skipping 14 matching lines...) Expand all
495 reading_list::prefs::kReadingListHasUnseenEntries); 476 reading_list::prefs::kReadingListHasUnseenEntries);
496 } 477 }
497 478
498 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() { 479 syncer::ModelTypeSyncBridge* ReadingListModelImpl::GetModelTypeSyncBridge() {
499 DCHECK(loaded()); 480 DCHECK(loaded());
500 if (!storage_layer_) 481 if (!storage_layer_)
501 return nullptr; 482 return nullptr;
502 return storage_layer_->GetModelTypeSyncBridge(); 483 return storage_layer_->GetModelTypeSyncBridge();
503 } 484 }
504 485
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() { 486 ReadingListModelStorage* ReadingListModelImpl::StorageLayer() {
515 return storage_layer_.get(); 487 return storage_layer_.get();
516 } 488 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698