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

Side by Side Diff: third_party/tcmalloc/chromium/src/ranked_list.h

Issue 986503002: components/metrics: Add runtime memory leak detector (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix error in leak analyzer logic Created 5 years, 6 months 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
(Empty)
1 // Copyright (c) 2015 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.
4
5 // ---
6 // Author: Simon Que
7
8 #ifndef _RANKED_LIST_H_
9 #define _RANKED_LIST_H_
10
11 #include <cstdio>
12 #include <cstring>
13
14 #include "base/basictypes.h"
15
16 // RankedList lets you add entries and automatically sorts them internally, so
17 // they can be accessed in sorted order. The entries are stored as a vector
18 // array.
19
20 namespace leak_detector {
21
22 template <typename T>
23 class RankedList {
24 public:
25 typedef void* (*Allocator)(size_t size);
26 typedef void (*DeAllocator)(void* ptr);
27
28 // A single entry in the RankedList. The RankedList sorts entries by |count|.
29 struct Entry {
30 int count;
31 T value;
32 };
33
34 RankedList(int max_size, Allocator alloc, DeAllocator dealloc);
35 ~RankedList();
36
37 RankedList& operator=(const RankedList& other);
38
39 // Access the array of entries.
40 const Entry* entries() const {
41 return entries_;
42 }
43 // Access individual element. Does not do boundary checking.
44 const Entry& entry(int index) const {
45 return entries_[index];
46 }
47 const int size() const {
48 return size_;
49 }
50
51 // Add a new value-count pair to the list. Does not check for existing entries
52 // with the same value.
53 void Add(const T& value, int count);
54
55 private:
56 // Returns the position to insert a new value. Returns -1 if it cannot be
57 // inserted.
58 int GetInsertionIndex(int count) const;
59
60 // Max and min counts.
61 const int max_count() const {
62 if (size_ == 0)
63 return 0;
64 return entries_[0].count;
65 }
66 const int min_count() const {
67 if (size_ == 0)
68 return 0;
69 return entries_[size_ - 1].count;
70 }
71
72 // For memory allocation.
73 Allocator alloc_;
74 DeAllocator dealloc_;
75
76 // Max items in the list.
77 int max_size_;
78
79 // The current number of items in the list.
80 int size_;
81
82 // Points to the array of entries.
83 Entry* entries_;
84 };
85
86 template <typename T>
87 RankedList<T>::RankedList(int max_size, Allocator alloc, DeAllocator dealloc)
88 : alloc_(alloc),
89 dealloc_(dealloc),
90 max_size_(max_size),
91 size_(0) {
92 // Allocate array of elements, with an extra element at end as an overflow
93 // bucket.
94 size_t entries_size = sizeof(Entry) * (max_size + 1);
95 entries_ = static_cast<Entry*>(alloc_(entries_size));
96 memset(entries_, 0, entries_size);
97 }
98
99 template <typename T>
100 RankedList<T>::~RankedList() {
101 dealloc_(entries_);
102 entries_ = NULL;
103 }
104
105 template <typename T>
106 RankedList<T>& RankedList<T>::operator=(const RankedList<T>& other) {
107 // Delete currently allocated memory.
108 dealloc_(entries_);
109 entries_ = NULL;
110
111 // Allocate the space for the new data.
112 max_size_ = other.max_size_;
113 size_t entries_size = sizeof(Entry) * (max_size_ + 1);
114 entries_ = static_cast<Entry*>(alloc_(entries_size));
115 memset(entries_, 0, entries_size);
116
117 // Copy over the new data.
118 size_ = other.size_;
119 memcpy(entries_, other.entries_, sizeof(Entry) * size_);
120 }
121
122 template <typename T>
123 void RankedList<T>::Add(const T& value, int count) {
124 // Determine where to insert the value.
125 int index = GetInsertionIndex(count);
126 if (index == -1)
127 return;
128 // Shift the other elements down. Use memmove to deal with source/dest
129 // overlaps.
130 memmove(&entries_[index + 1], &entries_[index],
131 (size_ - index) * sizeof(Entry));
132 // Finally, insert the new entry.
133 entries_[index].count = count;
134 entries_[index].value = value;
135 // Update size.
136 if (size_ < max_size_)
137 ++size_;
138 }
139
140 template <typename T>
141 int RankedList<T>::GetInsertionIndex(int count) const {
142 // If the list is full, do not add any entry with |count| if does not exceed
143 // the lowest count of the entries in the list.
144 if (size_ == max_size_ && count <= min_count())
145 return -1;
146 // If larger than the current largest item, insert it before.
147 if (count >= max_count())
148 return 0;
149 // If smaller than the current smallest item, but the list is not full,
150 // insert it after.
151 if (count <= min_count())
152 return size_;
153
154 // Otherwise it's somewhere in the middle, so look for it there.
155 int min_pos = 0;
156 int max_pos = size_ - 1;
157 while (max_pos >= min_pos) {
158 int midpoint = (max_pos + min_pos) / 2;
159 if (count >= entries_[midpoint].count &&
160 count <= entries_[midpoint - 1].count) {
161 return midpoint;
162 }
163 // The list is reverse sorted.
164 if (entries_[midpoint].count >= count)
165 min_pos = midpoint + 1;
166 else
167 max_pos = midpoint - 1;
168 }
169 return max_pos;
170 }
171
172 } // namespace leak_detector
173
174 #endif // _RANKED_LIST_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698