OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/metrics/persisted_logs.h" | 5 #include "components/metrics/persisted_logs.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/md5.h" | 10 #include "base/md5.h" |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
79 const char* pref_name, | 79 const char* pref_name, |
80 const char* old_pref_name, | 80 const char* old_pref_name, |
81 size_t min_log_count, | 81 size_t min_log_count, |
82 size_t min_log_bytes, | 82 size_t min_log_bytes, |
83 size_t max_log_size) | 83 size_t max_log_size) |
84 : local_state_(local_state), | 84 : local_state_(local_state), |
85 pref_name_(pref_name), | 85 pref_name_(pref_name), |
86 old_pref_name_(old_pref_name), | 86 old_pref_name_(old_pref_name), |
87 min_log_count_(min_log_count), | 87 min_log_count_(min_log_count), |
88 min_log_bytes_(min_log_bytes), | 88 min_log_bytes_(min_log_bytes), |
89 max_log_size_(max_log_size), | 89 max_log_size_(max_log_size ? max_log_size : static_cast<size_t>(-1)), |
Alexei Svitkine (slow)
2014/07/15 18:52:59
Can you use SIZE_MAX instead of casting -1 to a si
Steven Holte
2014/07/15 20:23:03
Done.
| |
90 last_provisional_store_index_(-1) { | 90 last_provisional_store_index_(-1) { |
91 DCHECK(local_state_); | 91 DCHECK(local_state_); |
92 // One of the limit arguments must be non-zero. | 92 // One of the limit arguments must be non-zero. |
93 DCHECK(min_log_count_ > 0 || min_log_bytes_ > 0); | 93 DCHECK(min_log_count_ > 0 || min_log_bytes_ > 0); |
94 } | 94 } |
95 | 95 |
96 PersistedLogs::~PersistedLogs() {} | 96 PersistedLogs::~PersistedLogs() {} |
97 | 97 |
98 void PersistedLogs::SerializeLogs() { | 98 void PersistedLogs::SerializeLogs() const { |
99 // Remove any logs that are over the serialization size limit. | |
100 if (max_log_size_) { | |
101 for (std::vector<LogHashPair>::iterator it = list_.begin(); | |
102 it != list_.end();) { | |
103 size_t log_size = it->compressed_log_data.length(); | |
104 if (log_size > max_log_size_) { | |
105 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted", | |
106 static_cast<int>(log_size)); | |
107 it = list_.erase(it); | |
108 } else { | |
109 ++it; | |
110 } | |
111 } | |
112 } | |
113 | |
114 ListPrefUpdate update(local_state_, pref_name_); | 99 ListPrefUpdate update(local_state_, pref_name_); |
115 WriteLogsToPrefList(update.Get()); | 100 WriteLogsToPrefList(update.Get()); |
116 | 101 |
117 // Clear the old pref now that we've written to the new one. | 102 // Clear the old pref now that we've written to the new one. |
118 // TODO(asvitkine): Remove the old pref in M39. | 103 // TODO(asvitkine): Remove the old pref in M39. |
119 local_state_->ClearPref(old_pref_name_); | 104 local_state_->ClearPref(old_pref_name_); |
120 } | 105 } |
121 | 106 |
122 PersistedLogs::LogReadStatus PersistedLogs::DeserializeLogs() { | 107 PersistedLogs::LogReadStatus PersistedLogs::DeserializeLogs() { |
123 // First, try reading from old pref. If it's empty, read from the new one. | 108 // First, try reading from old pref. If it's empty, read from the new one. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
162 } | 147 } |
163 | 148 |
164 void PersistedLogs::DiscardLastProvisionalStore() { | 149 void PersistedLogs::DiscardLastProvisionalStore() { |
165 if (last_provisional_store_index_ == -1) | 150 if (last_provisional_store_index_ == -1) |
166 return; | 151 return; |
167 DCHECK_LT(static_cast<size_t>(last_provisional_store_index_), list_.size()); | 152 DCHECK_LT(static_cast<size_t>(last_provisional_store_index_), list_.size()); |
168 list_.erase(list_.begin() + last_provisional_store_index_); | 153 list_.erase(list_.begin() + last_provisional_store_index_); |
169 last_provisional_store_index_ = -1; | 154 last_provisional_store_index_ = -1; |
170 } | 155 } |
171 | 156 |
172 void PersistedLogs::WriteLogsToPrefList(base::ListValue* list_value) { | 157 void PersistedLogs::WriteLogsToPrefList(base::ListValue* list_value) const { |
173 list_value->Clear(); | 158 list_value->Clear(); |
159 | |
160 // Keep the most recent logs which are smaller than max_log_size_. | |
Alexei Svitkine (slow)
2014/07/15 18:52:59
Nit: Surround variable names in |'s.
Steven Holte
2014/07/15 20:23:03
Done.
| |
161 // We keep at least min_log_bytes_ and min_log_count_ of logs before | |
162 // discarding older logs. | |
163 size_t start = list_.size(); | |
164 size_t saved_log_count = 0; | |
165 size_t bytes_used = 0; | |
166 for (; start > 0; --start) { | |
167 size_t log_size = list_[start-1].compressed_log_data.length(); | |
Alexei Svitkine (slow)
2014/07/15 18:52:59
Nit: spaces around the minus.
Steven Holte
2014/07/15 20:23:03
Done.
| |
168 if (bytes_used >= min_log_bytes_ && | |
169 saved_log_count >= min_log_count_) { | |
170 break; | |
171 } | |
172 // Oversized logs won't be persisted, so don't count them. | |
Alexei Svitkine (slow)
2014/07/15 18:52:59
I don't think the piece of code is needed, since t
Steven Holte
2014/07/15 20:23:03
The second loop iterates in the reverse direction
Steven Holte
2014/07/15 20:25:47
Also, I've now removed the early return below, sin
| |
173 if (log_size <= max_log_size_) { | |
174 bytes_used += log_size; | |
175 ++saved_log_count; | |
176 } | |
177 } | |
178 | |
174 // Leave the list completely empty if there are no storable values. | 179 // Leave the list completely empty if there are no storable values. |
175 if (list_.empty()) | 180 if (saved_log_count == 0) |
176 return; | 181 return; |
177 | 182 |
178 size_t start = 0; | 183 for (size_t i = start; i < list_.size(); ++i) { |
179 // If there are too many logs, keep the most recent logs up to the length | 184 size_t log_size = list_[i].compressed_log_data.length(); |
180 // limit, and at least to the minimum number of bytes. | 185 if (log_size > max_log_size_) { |
181 if (list_.size() > min_log_count_) { | 186 UMA_HISTOGRAM_COUNTS("UMA.Large Accumulated Log Not Persisted", |
182 start = list_.size(); | 187 static_cast<int>(log_size)); |
183 size_t bytes_used = 0; | 188 continue; |
184 std::vector<LogHashPair>::const_reverse_iterator end = list_.rend(); | |
185 for (std::vector<LogHashPair>::const_reverse_iterator it = list_.rbegin(); | |
186 it != end; ++it) { | |
187 const size_t log_size = it->compressed_log_data.length(); | |
188 if (bytes_used >= min_log_bytes_ && | |
189 (list_.size() - start) >= min_log_count_) { | |
190 break; | |
191 } | |
192 bytes_used += log_size; | |
193 --start; | |
194 } | 189 } |
195 } | |
196 DCHECK_LT(start, list_.size()); | |
197 | |
198 for (size_t i = start; i < list_.size(); ++i) { | |
199 AppendBase64String(list_[i].compressed_log_data, list_value); | 190 AppendBase64String(list_[i].compressed_log_data, list_value); |
200 AppendBase64String(list_[i].hash, list_value); | 191 AppendBase64String(list_[i].hash, list_value); |
201 } | 192 } |
202 } | 193 } |
203 | 194 |
204 PersistedLogs::LogReadStatus PersistedLogs::ReadLogsFromPrefList( | 195 PersistedLogs::LogReadStatus PersistedLogs::ReadLogsFromPrefList( |
205 const base::ListValue& list_value) { | 196 const base::ListValue& list_value) { |
206 if (list_value.empty()) | 197 if (list_value.empty()) |
207 return MakeRecallStatusHistogram(LIST_EMPTY); | 198 return MakeRecallStatusHistogram(LIST_EMPTY); |
208 | 199 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
289 return MakeRecallStatusHistogram(CHECKSUM_STRING_CORRUPTION); | 280 return MakeRecallStatusHistogram(CHECKSUM_STRING_CORRUPTION); |
290 } | 281 } |
291 if (recovered_md5 != base::MD5DigestToBase16(digest)) { | 282 if (recovered_md5 != base::MD5DigestToBase16(digest)) { |
292 list_.clear(); | 283 list_.clear(); |
293 return MakeRecallStatusHistogram(CHECKSUM_CORRUPTION); | 284 return MakeRecallStatusHistogram(CHECKSUM_CORRUPTION); |
294 } | 285 } |
295 return MakeRecallStatusHistogram(RECALL_SUCCESS); | 286 return MakeRecallStatusHistogram(RECALL_SUCCESS); |
296 } | 287 } |
297 | 288 |
298 } // namespace metrics | 289 } // namespace metrics |
OLD | NEW |