LogStatistics.h revision 6d981af12023bcaf22bfa0612a85ae4580ecb971
134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn/*
234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Copyright (C) 2014 The Android Open Source Project
334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *
434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Licensed under the Apache License, Version 2.0 (the "License");
534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * you may not use this file except in compliance with the License.
634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * You may obtain a copy of the License at
734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *
834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *      http://www.apache.org/licenses/LICENSE-2.0
934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn *
1034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * Unless required by applicable law or agreed to in writing, software
1134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * distributed under the License is distributed on an "AS IS" BASIS,
1234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * See the License for the specific language governing permissions and
1434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn * limitations under the License.
1534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn */
1634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
1734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#ifndef _LOGD_LOG_STATISTICS_H__
1834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define _LOGD_LOG_STATISTICS_H__
1934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
20720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn#include <memory>
21720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn#include <stdlib.h>
2234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <sys/types.h>
2334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
24758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <algorithm> // std::max
25758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <string>    // std::string
26511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn#include <unordered_map>
27511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
280dd4431072cce3c62876b728cb20aa5b77b11a8dMark Salyzyn#include <android/log.h>
294f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
30758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn#include <private/android_filesystem_config.h>
3197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
3297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include "LogBufferElement.h"
335ac5c6b19364b5b3061a59db796b2357c95c3b64Mark Salyzyn#include "LogUtils.h"
3434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
3534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define log_id_for_each(i) \
36f0f94fe49b04c2d2bf0a0a44a7afb9118607b351Chih-Hung Hsieh    for (log_id_t i = LOG_ID_MIN; (i) < LOG_ID_MAX; (i) = (log_id_t) ((i) + 1))
3734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
38758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynclass LogStatistics;
39758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
40720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyntemplate <typename TKey, typename TEntry>
41511338dd575572d567c04d69eaea60627b6c3452Mark Salyzynclass LogHashtable {
42511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
43511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    std::unordered_map<TKey, TEntry> map;
44511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
456d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t bucket_size() const {
466d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        size_t count = 0;
476d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        for (size_t idx = 0; idx < map.bucket_count(); ++idx) {
486d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size_t bucket_size = map.bucket_size(idx);
496d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (bucket_size == 0) bucket_size = 1;
506d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            count += bucket_size;
516d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
526d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        float load_factor = map.max_load_factor();
536d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        if (load_factor < 1.0) return count;
546d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return count * load_factor;
556d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
566d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
576d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    static const size_t unordered_map_per_entry_overhead = sizeof(void*);
586d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    static const size_t unordered_map_bucket_overhead = sizeof(void*);
596d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
60720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynpublic:
61511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
626d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    // Estimate unordered_map memory usage.
636d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t sizeOf() const {
646d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return sizeof(*this) +
656d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn               (map.size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) +
666d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn               (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead);
676d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
686d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
69511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
70758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
71511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
72ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid,
73ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                           size_t len) const {
74758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!len) {
75720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            std::unique_ptr<const TEntry *[]> sorted(NULL);
76720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return sorted;
77720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
79758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        const TEntry **retval = new const TEntry* [len];
80758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        memset(retval, 0, sizeof(*retval) * len);
81720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
82758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for(const_iterator it = map.begin(); it != map.end(); ++it) {
83511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            const TEntry &entry = it->second;
84ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
85ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if ((uid != AID_ROOT) && (uid != entry.getUid())) {
86ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
87ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
88ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if (pid && entry.getPid() && (pid != entry.getPid())) {
89ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
90ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
91ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
92758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            size_t sizes = entry.getSizes();
93758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            ssize_t index = len - 1;
94758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            while ((!retval[index] || (sizes > retval[index]->getSizes()))
95758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    && (--index >= 0))
96720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                ;
97758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (++index < (ssize_t)len) {
98758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                size_t num = len - index - 1;
99758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                if (num) {
100758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    memmove(&retval[index + 1], &retval[index],
101758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                            num * sizeof(retval[0]));
102720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
103758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                retval[index] = &entry;
104720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
105720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
106720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const TEntry *[]> sorted(retval);
107720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return sorted;
108720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
109720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
110758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline iterator add(TKey key, LogBufferElement *element) {
111511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
112511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
113758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(element))).first;
114511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
115758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.add(element);
11681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
117511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
11881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
11981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
120511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator add(TKey key) {
121511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
122511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
123511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(key))).first;
124511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
125511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.add(key);
12681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
127511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
12881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
12981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
130758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    void subtract(TKey key, LogBufferElement *element) {
131511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
132758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if ((it != map.end()) && it->second.subtract(element)) {
133511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            map.erase(it);
13481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
13581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
13681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
137758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void drop(TKey key, LogBufferElement *element) {
138511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
139511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it != map.end()) {
140758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.drop(element);
14181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
14281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
14381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
144511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator begin() { return map.begin(); }
145758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline const_iterator begin() const { return map.begin(); }
146511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator end() { return map.end(); }
147758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline const_iterator end() const { return map.end(); }
148758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(
150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const LogStatistics &stat,
151758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid_t uid,
152ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid_t pid,
153758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &name = std::string(""),
154758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            log_id_t id = LOG_ID_MAX) const {
155758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        static const size_t maximum_sorted_entries = 32;
156758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        std::string output;
157ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid,
158ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                                        maximum_sorted_entries);
159758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!sorted.get()) {
160758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return output;
161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
162758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        bool headerPrinted = false;
163758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for (size_t index = 0; index < maximum_sorted_entries; ++index) {
164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const TEntry *entry = sorted[index];
165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!entry) {
166758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
167758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
168758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!headerPrinted) {
172758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += "\n\n";
173758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += entry->formatHeader(name, id);
174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                headerPrinted = true;
175758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
176758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            output += entry->format(stat, id);
177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return output;
179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
1806d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
181720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
182720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants {
184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static constexpr size_t pruned_len = 14;
185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static constexpr size_t total_len = 80;
186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
18881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase {
18997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t size;
19034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase():size(0) { }
1929e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit EntryBase(LogBufferElement *element):size(element->getMsgLen()) { }
19334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t getSizes() const { return size; }
19581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
196758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) { size += element->getMsgLen(); }
197758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline bool subtract(LogBufferElement *element) {
198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        size -= element->getMsgLen();
199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return !size;
200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
201758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
202758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static std::string formatLine(
203758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &name,
204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &size,
205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &pruned) {
206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        ssize_t drop_len = std::max(pruned.length() + 1,
207758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                    EntryBaseConstants::pruned_len);
208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        ssize_t size_len = std::max(size.length() + 1,
209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                    EntryBaseConstants::total_len
210758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                        - name.length() - drop_len - 1);
211758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (pruned.length()) {
213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)size_len, size.c_str(),
215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)drop_len, pruned.c_str());
216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        } else {
217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return android::base::StringPrintf("%s%*s\n", name.c_str(),
218758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)size_len, size.c_str());
219758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
220758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
22181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
22281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
22381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase {
22481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t dropped;
22581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
22681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped():dropped(0) { }
2279e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit EntryBaseDropped(LogBufferElement *element):
228758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBase(element),
2296a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            dropped(element->getDropped()) {
230758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
23181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
232ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t getDropped() const { return dropped; }
233ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
234758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
235758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped += element->getDropped();
236758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::add(element);
23781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
238758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline bool subtract(LogBufferElement *element) {
239758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped -= element->getDropped();
240758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return EntryBase::subtract(element) && !dropped;
24181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void drop(LogBufferElement *element) {
24381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += 1;
244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::subtract(element);
24581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
24681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
24781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
24881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped {
24981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    const uid_t uid;
250ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
25181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
2529e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit UidEntry(LogBufferElement *element):
253758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
254ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            uid(element->getUid()),
255ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()) {
256758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
25781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
25881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline const uid_t&getKey() const { return uid; }
259ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline const uid_t&getUid() const { return getKey(); }
260ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline const pid_t&getPid() const { return pid; }
261ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
262ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline void add(LogBufferElement *element) {
263ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
264ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
265ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
266ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        EntryBase::add(element);
267ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    }
268758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
269758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
270758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
27134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
27234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
27381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android {
27481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid);
27581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}
27681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
27781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped {
278720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t pid;
279720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
280720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    char *name;
281720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
2829e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit PidEntry(pid_t pid):
283758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(),
284758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(pid),
285758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(android::pidToUid(pid)),
286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::pidToName(pid)) {
287758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
2889e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit PidEntry(LogBufferElement *element):
289758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
290758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(element->getPid()),
291758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()),
292758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::pidToName(pid)) {
293758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
294758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    PidEntry(const PidEntry &element):
295758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
296758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(element.pid),
297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element.uid),
298758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(element.name ? strdup(element.name) : NULL) {
299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
300720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ~PidEntry() { free(name); }
301720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
302720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t&getKey() const { return pid; }
303ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return getKey(); }
304720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const uid_t&getUid() const { return uid; }
305720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const char*getName() const { return name; }
30681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
307758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t newPid) {
308ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn        if (name && !fast<strncmp>(name, "zygote", 6)) {
309aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            free(name);
310aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            name = NULL;
311aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        }
31281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (!name) {
313758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(newPid);
31481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
31581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
31681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
317758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
318758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
319758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (getUid() != incomingUid) {
320758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
32181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            free(name);
322758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(element->getPid());
32381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        } else {
324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getPid());
32581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
326758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
32781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
328758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
329758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
330758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
331344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn};
332344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
33317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped {
33417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t tid;
335ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
33617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    uid_t uid;
33717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    char *name;
33817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
339ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    TidEntry(pid_t tid, pid_t pid):
340758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(),
341758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(tid),
342ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(pid),
343758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(android::pidToUid(tid)),
344758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::tidToName(tid)) {
345758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
3469e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit TidEntry(LogBufferElement *element):
347758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
348758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(element->getTid()),
349ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()),
350758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()),
351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::tidToName(tid)) {
352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
353758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    TidEntry(const TidEntry &element):
354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(element.tid),
356ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element.pid),
357758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element.uid),
358758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(element.name ? strdup(element.name) : NULL) {
359758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
36017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    ~TidEntry() { free(name); }
36117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
36217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t&getKey() const { return tid; }
363ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getTid() const { return getKey(); }
364ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return pid; }
36517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const uid_t&getUid() const { return uid; }
36617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const char*getName() const { return name; }
36717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t incomingTid) {
369ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn        if (name && !fast<strncmp>(name, "zygote", 6)) {
37017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
37117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            name = NULL;
37217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
37317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (!name) {
374758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(incomingTid);
37517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
37617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
37717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
378758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
379758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
380ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        pid_t incomingPid = element->getPid();
381ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
382758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
383ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = incomingPid;
38417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
385758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(element->getTid());
38617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        } else {
387758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getTid());
38817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
389758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
39017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
391758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
392758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
393758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
39417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn};
39517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
3966a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynstruct TagEntry : public EntryBaseDropped {
397344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t tag;
398ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
399344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    uid_t uid;
400344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
4019e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit TagEntry(LogBufferElement *element):
4026a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            EntryBaseDropped(element),
403758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tag(element->getTag()),
404ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()),
405758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()) {
406758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
407344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
408344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t&getKey() const { return tag; }
409ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return pid; }
410344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uid_t&getUid() const { return uid; }
411807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn    const char*getName(size_t &len) const { return android::tagToName(&len, tag); }
41281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
413758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
414ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (uid != element->getUid()) {
415344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn            uid = -1;
416344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        }
417ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
418ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
419ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
420758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::add(element);
421344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
422758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
423758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
424758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
425720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
426720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
4276a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyntemplate <typename TEntry>
4286a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynclass LogFindWorst {
4296a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    std::unique_ptr<const TEntry *[]> sorted;
4306a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4316a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynpublic:
4326a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4339e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit LogFindWorst(std::unique_ptr<const TEntry *[]> &&sorted) : sorted(std::move(sorted)) { }
4346a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4356a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    void findWorst(int &worst,
4366a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    size_t &worst_sizes, size_t &second_worst_sizes,
4376a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    size_t threshold) {
4386a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (sorted.get() && sorted[0] && sorted[1]) {
4396a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            worst_sizes = sorted[0]->getSizes();
4406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            if ((worst_sizes > threshold)
4416a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                // Allow time horizon to extend roughly tenfold, assume
4426a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                // average entry length is 100 characters.
4436a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    && (worst_sizes > (10 * sorted[0]->getDropped()))) {
4446a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                worst = sorted[0]->getKey();
4456a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                second_worst_sizes = sorted[1]->getSizes();
4466a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                if (second_worst_sizes < threshold) {
4476a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    second_worst_sizes = threshold;
4486a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                }
4496a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            }
4506a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
4516a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
4526a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4536a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    void findWorst(int &worst,
4546a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    size_t worst_sizes, size_t &second_worst_sizes) {
4556a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (sorted.get() && sorted[0] && sorted[1]) {
4566a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            worst = sorted[0]->getKey();
4576a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            second_worst_sizes = worst_sizes
4586a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                               - sorted[0]->getSizes()
4596a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                               + sorted[1]->getSizes();
4606a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
4616a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
4626a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn};
4636a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
46434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics
46534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics {
466c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn    friend UidEntry;
467c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn
46834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mSizes[LOG_ID_MAX];
46934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mElements[LOG_ID_MAX];
47058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t mDroppedElements[LOG_ID_MAX];
47197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mSizesTotal[LOG_ID_MAX];
47297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mElementsTotal[LOG_ID_MAX];
473720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    bool enable;
47434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
47597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // uid to size list
476720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
47797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t uidTable[LOG_ID_MAX];
478e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
479bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    // pid of system to size list
480bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t;
481bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    pidSystemTable_t pidSystemTable[LOG_ID_MAX];
482bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
483720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // pid to uid list
484720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
485720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pidTable_t pidTable;
486720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
48717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    // tid to uid list
48817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    typedef LogHashtable<pid_t, TidEntry> tidTable_t;
48917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    tidTable_t tidTable;
49017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
491344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    // tag list
492344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
493344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    tagTable_t tagTable;
494344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
495083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    // security tag list
496083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    tagTable_t securityTagTable;
497083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
4986d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t sizeOf() const {
4996d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() +
5006d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn                      tagTable.sizeOf() + securityTagTable.sizeOf();
5016d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        for(auto it : pidTable) {
5026d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            const char* name = it.second.getName();
5036d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (name) size += strlen(name) + 1;
5046d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
5056d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        for(auto it : tidTable) {
5066d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            const char* name = it.second.getName();
5076d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (name) size += strlen(name) + 1;
5086d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
5096d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        log_id_for_each(id) {
5106d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size += uidTable[id].sizeOf();
5116d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size += pidSystemTable[id].sizeOf();
5126d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
5136d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return size;
5146d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
5156d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
51634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic:
5176d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
51834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    LogStatistics();
51934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
520720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    void enableStatistics() { enable = true; }
52134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
52297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void add(LogBufferElement *entry);
52397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void subtract(LogBufferElement *entry);
524ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // entry->setDropped(1) must follow this call
525ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void drop(LogBufferElement *entry);
526aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn    // Correct for coalescing two entries referencing dropped content
52758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    void erase(LogBufferElement *element) {
52858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        log_id_t log_id = element->getLogId();
52958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mElements[log_id];
53058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mDroppedElements[log_id];
53158b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
532e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
5336a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) {
5346a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len));
5356a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
5366a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) {
5376a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len));
538758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
5396a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) {
5406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len));
541bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
54234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
54334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // fast track current value by id only
54434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes(log_id_t id) const { return mSizes[id]; }
54534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements(log_id_t id) const { return mElements[id]; }
54658b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t realElements(log_id_t id) const {
54758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        return mElements[id] - mDroppedElements[id];
54858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
54997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
55097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
55134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
552ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
5539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
554ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn    // helper (must be locked directly or implicitly by mLogElementsLock)
555758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *pidToName(pid_t pid) const;
5564ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    uid_t pidToUid(pid_t pid);
557758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *uidToName(uid_t uid) const;
55834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
55934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
56034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__
561