Make sure webrtc::VideoSource is released when WebRtcVideoTrackAdapter is destroyed.
[chromium-blink-merge.git] / components / dom_distiller / core / dom_distiller_model.cc
blobc0b2e6d3622398338cc015bb49547de3bcc22e04
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/dom_distiller/core/dom_distiller_model.h"
7 #include <utility>
9 using syncer::SyncChange;
10 using syncer::SyncChangeList;
11 using syncer::SyncData;
12 using syncer::SyncDataList;
14 namespace dom_distiller {
16 DomDistillerModel::DomDistillerModel()
17 : next_key_(1) {}
19 DomDistillerModel::DomDistillerModel(
20 const std::vector<ArticleEntry>& initial_data)
21 : next_key_(1) {
22 for (size_t i = 0; i < initial_data.size(); ++i) {
23 AddEntry(initial_data[i]);
27 DomDistillerModel::~DomDistillerModel() {}
29 bool DomDistillerModel::GetEntryById(const std::string& entry_id,
30 ArticleEntry* entry) const {
31 KeyType key = 0;
32 if (!GetKeyById(entry_id, &key)) {
33 return false;
35 GetEntryByKey(key, entry);
36 return true;
39 bool DomDistillerModel::GetEntryByUrl(const GURL& url,
40 ArticleEntry* entry) const {
41 KeyType key = 0;
42 if (!GetKeyByUrl(url, &key)) {
43 return false;
45 GetEntryByKey(key, entry);
46 return true;
49 bool DomDistillerModel::GetKeyById(const std::string& entry_id,
50 KeyType* key) const {
51 StringToKeyMap::const_iterator it = entry_id_to_key_map_.find(entry_id);
52 if (it == entry_id_to_key_map_.end()) {
53 return false;
55 if (key != NULL) {
56 *key = it->second;
58 return true;
61 bool DomDistillerModel::GetKeyByUrl(const GURL& url, KeyType* key) const {
62 StringToKeyMap::const_iterator it = url_to_key_map_.find(url.spec());
63 if (it == url_to_key_map_.end()) {
64 return false;
66 if (key != NULL) {
67 *key = it->second;
69 return true;
72 void DomDistillerModel::GetEntryByKey(KeyType key, ArticleEntry* entry) const {
73 if (entry != NULL) {
74 EntryMap::const_iterator it = entries_.find(key);
75 DCHECK(it != entries_.end());
76 *entry = it->second;
80 size_t DomDistillerModel::GetNumEntries() const {
81 return entries_.size();
84 std::vector<ArticleEntry> DomDistillerModel::GetEntries() const {
85 std::vector<ArticleEntry> entries_list;
86 for (EntryMap::const_iterator it = entries_.begin(); it != entries_.end();
87 ++it) {
88 entries_list.push_back(it->second);
90 return entries_list;
93 SyncDataList DomDistillerModel::GetAllSyncData() const {
94 SyncDataList data;
95 for (EntryMap::const_iterator it = entries_.begin(); it != entries_.end();
96 ++it) {
97 data.push_back(CreateLocalData(it->second));
99 return data;
102 void DomDistillerModel::CalculateChangesForMerge(
103 const SyncDataList& data,
104 SyncChangeList* changes_to_apply,
105 SyncChangeList* changes_missing) {
106 typedef base::hash_set<std::string> StringSet;
107 StringSet entries_to_change;
108 for (SyncDataList::const_iterator it = data.begin(); it != data.end(); ++it) {
109 std::string entry_id = GetEntryIdFromSyncData(*it);
110 std::pair<StringSet::iterator, bool> insert_result =
111 entries_to_change.insert(entry_id);
113 DCHECK(insert_result.second);
115 SyncChange::SyncChangeType change_type = SyncChange::ACTION_ADD;
116 if (GetEntryById(entry_id, NULL)) {
117 change_type = SyncChange::ACTION_UPDATE;
119 changes_to_apply->push_back(SyncChange(FROM_HERE, change_type, *it));
122 for (EntryMap::const_iterator it = entries_.begin(); it != entries_.end();
123 ++it) {
124 if (entries_to_change.find(it->second.entry_id()) ==
125 entries_to_change.end()) {
126 changes_missing->push_back(SyncChange(
127 FROM_HERE, SyncChange::ACTION_ADD, CreateLocalData(it->second)));
132 void DomDistillerModel::ApplyChangesToModel(
133 const SyncChangeList& changes,
134 SyncChangeList* changes_applied,
135 SyncChangeList* changes_missing) {
136 DCHECK(changes_applied);
137 DCHECK(changes_missing);
139 for (SyncChangeList::const_iterator it = changes.begin(); it != changes.end();
140 ++it) {
141 ApplyChangeToModel(*it, changes_applied, changes_missing);
145 void DomDistillerModel::AddEntry(const ArticleEntry& entry) {
146 const std::string& entry_id = entry.entry_id();
147 KeyType key = next_key_++;
148 DCHECK(!GetKeyById(entry_id, NULL));
149 entries_.insert(std::make_pair(key, entry));
150 entry_id_to_key_map_.insert(std::make_pair(entry_id, key));
151 for (int i = 0; i < entry.pages_size(); ++i) {
152 url_to_key_map_.insert(std::make_pair(entry.pages(i).url(), key));
156 void DomDistillerModel::RemoveEntry(const ArticleEntry& entry) {
157 const std::string& entry_id = entry.entry_id();
158 KeyType key = 0;
159 bool success = GetKeyById(entry_id, &key);
160 DCHECK(success);
162 entries_.erase(key);
163 entry_id_to_key_map_.erase(entry_id);
164 for (int i = 0; i < entry.pages_size(); ++i) {
165 url_to_key_map_.erase(entry.pages(i).url());
169 void DomDistillerModel::ApplyChangeToModel(
170 const SyncChange& change,
171 SyncChangeList* changes_applied,
172 SyncChangeList* changes_missing) {
173 DCHECK(change.IsValid());
174 DCHECK(changes_applied);
175 DCHECK(changes_missing);
177 const std::string& entry_id = GetEntryIdFromSyncData(change.sync_data());
179 if (change.change_type() == SyncChange::ACTION_DELETE) {
180 ArticleEntry current_entry;
181 if (GetEntryById(entry_id, &current_entry)) {
182 RemoveEntry(current_entry);
183 changes_applied->push_back(SyncChange(
184 change.location(), SyncChange::ACTION_DELETE, change.sync_data()));
186 // If we couldn't find in sync db, we were deleting anyway so swallow the
187 // error.
188 return;
191 ArticleEntry entry = GetEntryFromChange(change);
192 ArticleEntry current_entry;
193 if (!GetEntryById(entry_id, &current_entry)) {
194 AddEntry(entry);
195 changes_applied->push_back(SyncChange(
196 change.location(), SyncChange::ACTION_ADD, change.sync_data()));
197 } else {
198 if (!AreEntriesEqual(current_entry, entry)) {
199 // Currently, conflicts are simply resolved by accepting the last one to
200 // arrive.
201 RemoveEntry(current_entry);
202 AddEntry(entry);
203 changes_applied->push_back(SyncChange(
204 change.location(), SyncChange::ACTION_UPDATE, change.sync_data()));
209 } // namespace dom_distiller