| Index: base/metrics/persistent_sample_map.cc
|
| diff --git a/base/metrics/persistent_sample_map.cc b/base/metrics/persistent_sample_map.cc
|
| index cc20f45412bec2160f62dfb7aa9380e6b9a4caca..f61e53c164fc9961b277cb495b230abda5fb76fd 100644
|
| --- a/base/metrics/persistent_sample_map.cc
|
| +++ b/base/metrics/persistent_sample_map.cc
|
| @@ -131,7 +131,7 @@ Count PersistentSampleMap::GetCount(Sample value) const {
|
| Count PersistentSampleMap::TotalCount() const {
|
| // Have to override "const" in order to make sure all samples have been
|
| // loaded before trying to iterate over the map.
|
| - const_cast<PersistentSampleMap*>(this)->ImportSamples(kAllSamples);
|
| + const_cast<PersistentSampleMap*>(this)->ImportSamples(-1, true);
|
|
|
| Count count = 0;
|
| for (const auto& entry : sample_counts_) {
|
| @@ -143,7 +143,7 @@ Count PersistentSampleMap::TotalCount() const {
|
| std::unique_ptr<SampleCountIterator> PersistentSampleMap::Iterator() const {
|
| // Have to override "const" in order to make sure all samples have been
|
| // loaded before trying to iterate over the map.
|
| - const_cast<PersistentSampleMap*>(this)->ImportSamples(kAllSamples);
|
| + const_cast<PersistentSampleMap*>(this)->ImportSamples(-1, true);
|
| return WrapUnique(new PersistentSampleMapIterator(sample_counts_));
|
| }
|
|
|
| @@ -204,15 +204,13 @@ bool PersistentSampleMap::AddSubtractImpl(SampleCountIterator* iter,
|
| }
|
|
|
| Count* PersistentSampleMap::GetSampleCountStorage(Sample value) {
|
| - DCHECK_LE(0, value);
|
| -
|
| // If |value| is already in the map, just return that.
|
| auto it = sample_counts_.find(value);
|
| if (it != sample_counts_.end())
|
| return it->second;
|
|
|
| // Import any new samples from persistent memory looking for the value.
|
| - return ImportSamples(value);
|
| + return ImportSamples(value, false);
|
| }
|
|
|
| Count* PersistentSampleMap::GetOrCreateSampleCountStorage(Sample value) {
|
| @@ -242,12 +240,14 @@ Count* PersistentSampleMap::GetOrCreateSampleCountStorage(Sample value) {
|
| // Thread-safety within a process where multiple threads use the same
|
| // histogram object is delegated to the controlling histogram object which,
|
| // for sparse histograms, is a lock object.
|
| - count_pointer = ImportSamples(value);
|
| + count_pointer = ImportSamples(value, false);
|
| DCHECK(count_pointer);
|
| return count_pointer;
|
| }
|
|
|
| -Count* PersistentSampleMap::ImportSamples(Sample until_value) {
|
| +Count* PersistentSampleMap::ImportSamples(Sample until_value,
|
| + bool import_everything) {
|
| + Count* found_count = nullptr;
|
| PersistentMemoryAllocator::Reference ref;
|
| while ((ref = records_->GetNext()) != 0) {
|
| SampleRecord* record =
|
| @@ -259,9 +259,8 @@ Count* PersistentSampleMap::ImportSamples(Sample until_value) {
|
|
|
| // Check if the record's value is already known.
|
| if (!ContainsKey(sample_counts_, record->value)) {
|
| - // No: Add it to map of known values if the value is valid.
|
| - if (record->value >= 0)
|
| - sample_counts_[record->value] = &record->count;
|
| + // No: Add it to map of known values.
|
| + sample_counts_[record->value] = &record->count;
|
| } else {
|
| // Yes: Ignore it; it's a duplicate caused by a race condition -- see
|
| // code & comment in GetOrCreateSampleCountStorage() for details.
|
| @@ -269,12 +268,19 @@ Count* PersistentSampleMap::ImportSamples(Sample until_value) {
|
| DCHECK_EQ(0, record->count);
|
| }
|
|
|
| - // Stop if it's the value being searched for.
|
| - if (record->value == until_value)
|
| - return &record->count;
|
| + // Check if it's the value being searched for and, if so, keep a pointer
|
| + // to return later. Stop here unless everything is being imported.
|
| + // Because race conditions can cause multiple records for a single value,
|
| + // be sure to return the first one found.
|
| + if (record->value == until_value) {
|
| + if (!found_count)
|
| + found_count = &record->count;
|
| + if (!import_everything)
|
| + break;
|
| + }
|
| }
|
|
|
| - return nullptr;
|
| + return found_count;
|
| }
|
|
|
| } // namespace base
|
|
|