LogStatistics.h revision 3296291cffd13af13ea9e60a8ac1138101cf8e4c
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
62b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn    size_t size() const { return map.size(); }
63b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn
646d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    // Estimate unordered_map memory usage.
656d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t sizeOf() const {
666d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return sizeof(*this) +
67b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn               (size() * (sizeof(TEntry) + unordered_map_per_entry_overhead)) +
686d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn               (bucket_size() * sizeof(size_t) + unordered_map_bucket_overhead);
696d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
706d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
71511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
72758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
73511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
74ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid,
75ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                           size_t len) const {
76758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!len) {
77720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            std::unique_ptr<const TEntry *[]> sorted(NULL);
78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return sorted;
79720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
81758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        const TEntry **retval = new const TEntry* [len];
82758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        memset(retval, 0, sizeof(*retval) * len);
83720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
84758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for(const_iterator it = map.begin(); it != map.end(); ++it) {
85511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            const TEntry &entry = it->second;
86ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
87ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if ((uid != AID_ROOT) && (uid != entry.getUid())) {
88ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
89ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
90ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if (pid && entry.getPid() && (pid != entry.getPid())) {
91ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
92ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
93ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
94758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            size_t sizes = entry.getSizes();
95758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            ssize_t index = len - 1;
96758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            while ((!retval[index] || (sizes > retval[index]->getSizes()))
97758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    && (--index >= 0))
98720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                ;
99758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (++index < (ssize_t)len) {
100758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                size_t num = len - index - 1;
101758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                if (num) {
102758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    memmove(&retval[index + 1], &retval[index],
103758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                            num * sizeof(retval[0]));
104720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
105758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                retval[index] = &entry;
106720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
107720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
108720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const TEntry *[]> sorted(retval);
109720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return sorted;
110720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
111720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
112758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline iterator add(TKey key, LogBufferElement *element) {
113511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
114511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
115758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(element))).first;
116511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
117758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.add(element);
11881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
119511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
12081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
12181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
122511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator add(TKey key) {
123511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
124511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
125511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(key))).first;
126511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
127511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.add(key);
12881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
129511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
13081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
13181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
132758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    void subtract(TKey key, LogBufferElement *element) {
133511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
134758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if ((it != map.end()) && it->second.subtract(element)) {
135511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            map.erase(it);
13681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
13781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
13881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
139758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void drop(TKey key, LogBufferElement *element) {
140511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
141511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it != map.end()) {
142758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.drop(element);
14381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
14481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
14581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
146511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator begin() { return map.begin(); }
147758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline const_iterator begin() const { return map.begin(); }
148511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator end() { return map.end(); }
149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline const_iterator end() const { return map.end(); }
150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
151758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(
152758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const LogStatistics &stat,
153758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid_t uid,
154ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid_t pid,
155758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &name = std::string(""),
156758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            log_id_t id = LOG_ID_MAX) const {
157758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        static const size_t maximum_sorted_entries = 32;
158758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        std::string output;
159ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid,
160ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                                        maximum_sorted_entries);
161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!sorted.get()) {
162758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return output;
163758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        bool headerPrinted = false;
165758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for (size_t index = 0; index < maximum_sorted_entries; ++index) {
166758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const TEntry *entry = sorted[index];
167758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!entry) {
168758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
170758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
171758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
172758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
173758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!headerPrinted) {
174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += "\n\n";
175758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += entry->formatHeader(name, id);
176758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                headerPrinted = true;
177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            output += entry->format(stat, id);
179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
180758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return output;
181758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
1826d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
183720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
184720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants {
186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static constexpr size_t pruned_len = 14;
187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static constexpr size_t total_len = 80;
188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
19081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase {
19197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t size;
19234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase():size(0) { }
1949e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit EntryBase(LogBufferElement *element):size(element->getMsgLen()) { }
19534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
19697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t getSizes() const { return size; }
19781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
198758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) { size += element->getMsgLen(); }
199758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline bool subtract(LogBufferElement *element) {
200758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        size -= element->getMsgLen();
201758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return !size;
202758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
203758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static std::string formatLine(
205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &name,
206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &size,
207758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &pruned) {
208758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        ssize_t drop_len = std::max(pruned.length() + 1,
209758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                    EntryBaseConstants::pruned_len);
210758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        ssize_t size_len = std::max(size.length() + 1,
211758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                    EntryBaseConstants::total_len
212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                        - name.length() - drop_len - 1);
213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
214758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (pruned.length()) {
215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)size_len, size.c_str(),
217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)drop_len, pruned.c_str());
218758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        } else {
219758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return android::base::StringPrintf("%s%*s\n", name.c_str(),
220758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)size_len, size.c_str());
221758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
222758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
22381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
22481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
22581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase {
22681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t dropped;
22781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
22881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped():dropped(0) { }
2299e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit EntryBaseDropped(LogBufferElement *element):
230758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBase(element),
2316a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            dropped(element->getDropped()) {
232758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
23381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
234ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t getDropped() const { return dropped; }
235ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
236758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
237758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped += element->getDropped();
238758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::add(element);
23981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
240758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline bool subtract(LogBufferElement *element) {
241758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped -= element->getDropped();
242758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return EntryBase::subtract(element) && !dropped;
24381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
244758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void drop(LogBufferElement *element) {
24581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += 1;
246758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::subtract(element);
24781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
24881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
24981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
25081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped {
25181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    const uid_t uid;
252ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
25381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
2549e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit UidEntry(LogBufferElement *element):
255758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
256ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            uid(element->getUid()),
257ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()) {
258758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
25981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
26081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline const uid_t&getKey() const { return uid; }
261ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline const uid_t&getUid() const { return getKey(); }
262ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline const pid_t&getPid() const { return pid; }
263ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
264ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline void add(LogBufferElement *element) {
265ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
266ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
267ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
268a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        EntryBaseDropped::add(element);
269ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    }
270758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
271758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
272758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
27334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
27434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
27581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android {
27681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid);
27781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}
27881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
27981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped {
280720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t pid;
281720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
282720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    char *name;
283720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
2849e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit PidEntry(pid_t pid):
285758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(),
286758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(pid),
287758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(android::pidToUid(pid)),
288758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::pidToName(pid)) {
289758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
2909e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit PidEntry(LogBufferElement *element):
291758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
292758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(element->getPid()),
293758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()),
294758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::pidToName(pid)) {
295758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
296758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    PidEntry(const PidEntry &element):
297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
298758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(element.pid),
299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element.uid),
300758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(element.name ? strdup(element.name) : NULL) {
301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
302720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ~PidEntry() { free(name); }
303720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
304720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t&getKey() const { return pid; }
305ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return getKey(); }
306720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const uid_t&getUid() const { return uid; }
307720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const char*getName() const { return name; }
30881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
309758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t newPid) {
3100eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn        if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
311aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            free(name);
312aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            name = NULL;
313aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        }
31481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (!name) {
315758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(newPid);
31681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
31781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
31881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
319758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
320758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (getUid() != incomingUid) {
322758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
32381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            free(name);
324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(element->getPid());
32581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        } else {
326758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getPid());
32781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
328758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
32981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
330758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
331758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
332758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
333344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn};
334344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
33517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped {
33617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t tid;
337ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
33817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    uid_t uid;
33917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    char *name;
34017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
341ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    TidEntry(pid_t tid, pid_t pid):
342758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(),
343758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(tid),
344ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(pid),
345758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(android::pidToUid(tid)),
346758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::tidToName(tid)) {
347758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
3489e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit TidEntry(LogBufferElement *element):
349758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
350758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(element->getTid()),
351ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()),
352758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()),
353758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::tidToName(tid)) {
354758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    TidEntry(const TidEntry &element):
356758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
357758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(element.tid),
358ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element.pid),
359758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element.uid),
360758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(element.name ? strdup(element.name) : NULL) {
361758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
36217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    ~TidEntry() { free(name); }
36317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
36417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t&getKey() const { return tid; }
365ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getTid() const { return getKey(); }
366ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return pid; }
36717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const uid_t&getUid() const { return uid; }
36817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const char*getName() const { return name; }
36917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t incomingTid) {
3710eeb06b932f185e10377e4494475d2cdd6adfa1bMark Salyzyn        if (name && !fastcmp<strncmp>(name, "zygote", 6)) {
37217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
37317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            name = NULL;
37417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
37517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (!name) {
376758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(incomingTid);
37717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
37817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
37917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
380758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
381758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
382ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        pid_t incomingPid = element->getPid();
383ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
384758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
385ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = incomingPid;
38617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
387758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(element->getTid());
38817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        } else {
389758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getTid());
39017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
391758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
39217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
393758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
394758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
395758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
39617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn};
39717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
3986a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynstruct TagEntry : public EntryBaseDropped {
399344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t tag;
400ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
401344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    uid_t uid;
402344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
4039e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit TagEntry(LogBufferElement *element):
4046a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            EntryBaseDropped(element),
405758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tag(element->getTag()),
406ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()),
407758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()) {
408758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
409344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
410344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t&getKey() const { return tag; }
411ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return pid; }
412344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uid_t&getUid() const { return uid; }
413807e40ecc9786755e2f74a7a6a9b20c812588119Mark Salyzyn    const char*getName(size_t &len) const { return android::tagToName(&len, tag); }
41481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
415758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
416ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (uid != element->getUid()) {
417344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn            uid = -1;
418344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        }
419ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
420ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
421ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
422a2c022257c5bed56fbc47de25c5d909bbe880f7bMark Salyzyn        EntryBaseDropped::add(element);
423344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
424758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
425758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
426758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
427720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
428720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
4296a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyntemplate <typename TEntry>
4306a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynclass LogFindWorst {
4316a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    std::unique_ptr<const TEntry *[]> sorted;
4326a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4336a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzynpublic:
4346a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4359e70ba6352ad1ee4fdb3f70a8945c2985638de77Chih-Hung Hsieh    explicit LogFindWorst(std::unique_ptr<const TEntry *[]> &&sorted) : sorted(std::move(sorted)) { }
4366a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4376a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    void findWorst(int &worst,
4386a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    size_t &worst_sizes, size_t &second_worst_sizes,
4396a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    size_t threshold) {
4406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (sorted.get() && sorted[0] && sorted[1]) {
4416a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            worst_sizes = sorted[0]->getSizes();
4426a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            if ((worst_sizes > threshold)
4436a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                // Allow time horizon to extend roughly tenfold, assume
4446a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                // average entry length is 100 characters.
4456a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    && (worst_sizes > (10 * sorted[0]->getDropped()))) {
4466a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                worst = sorted[0]->getKey();
4476a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                second_worst_sizes = sorted[1]->getSizes();
4486a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                if (second_worst_sizes < threshold) {
4496a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    second_worst_sizes = threshold;
4506a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                }
4516a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            }
4526a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
4536a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
4546a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
4556a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    void findWorst(int &worst,
4566a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                    size_t worst_sizes, size_t &second_worst_sizes) {
4576a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        if (sorted.get() && sorted[0] && sorted[1]) {
4586a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            worst = sorted[0]->getKey();
4596a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn            second_worst_sizes = worst_sizes
4606a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                               - sorted[0]->getSizes()
4616a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn                               + sorted[1]->getSizes();
4626a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        }
4636a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
4646a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn};
4656a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn
46634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics
46734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics {
468c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn    friend UidEntry;
469c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn
47034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mSizes[LOG_ID_MAX];
47134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mElements[LOG_ID_MAX];
47258b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t mDroppedElements[LOG_ID_MAX];
47397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mSizesTotal[LOG_ID_MAX];
47497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mElementsTotal[LOG_ID_MAX];
4753296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn    static size_t SizesTotal;
476720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    bool enable;
47734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
47897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // uid to size list
479720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
48097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t uidTable[LOG_ID_MAX];
481e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
482bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    // pid of system to size list
483bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidSystemTable_t;
484bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    pidSystemTable_t pidSystemTable[LOG_ID_MAX];
485bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn
486720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // pid to uid list
487720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
488720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pidTable_t pidTable;
489720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
49017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    // tid to uid list
49117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    typedef LogHashtable<pid_t, TidEntry> tidTable_t;
49217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    tidTable_t tidTable;
49317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
494344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    // tag list
495344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
496344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    tagTable_t tagTable;
497344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
498083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    // security tag list
499083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    tagTable_t securityTagTable;
500083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
5016d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    size_t sizeOf() const {
5026d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        size_t size = sizeof(*this) + pidTable.sizeOf() + tidTable.sizeOf() +
503b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn                      tagTable.sizeOf() + securityTagTable.sizeOf() +
504b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn                      (pidTable.size() * sizeof(pidTable_t::iterator)) +
505b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn                      (tagTable.size() * sizeof(tagTable_t::iterator));
5066d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        for(auto it : pidTable) {
5076d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            const char* name = it.second.getName();
5086d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (name) size += strlen(name) + 1;
5096d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
5106d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        for(auto it : tidTable) {
5116d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            const char* name = it.second.getName();
5126d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            if (name) size += strlen(name) + 1;
5136d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
5146d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        log_id_for_each(id) {
5156d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size += uidTable[id].sizeOf();
516b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn            size += uidTable[id].size() * sizeof(uidTable_t::iterator);
5176d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn            size += pidSystemTable[id].sizeOf();
518b0672290e320113f4b6d8fc6bb2d1e0afe493c5cMark Salyzyn            size += pidSystemTable[id].size() * sizeof(pidSystemTable_t::iterator);
5196d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        }
5206d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn        return size;
5216d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn    }
5226d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
52334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic:
5246d981af12023bcaf22bfa0612a85ae4580ecb971Mark Salyzyn
52534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    LogStatistics();
52634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
527720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    void enableStatistics() { enable = true; }
52834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
52997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void add(LogBufferElement *entry);
53097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void subtract(LogBufferElement *entry);
531ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // entry->setDropped(1) must follow this call
532ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void drop(LogBufferElement *entry);
533aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn    // Correct for coalescing two entries referencing dropped content
53458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    void erase(LogBufferElement *element) {
53558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        log_id_t log_id = element->getLogId();
53658b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mElements[log_id];
53758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mDroppedElements[log_id];
53858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
539e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
5406a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<UidEntry> sort(uid_t uid, pid_t pid, size_t len, log_id id) {
5416a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<UidEntry>(uidTable[id].sort(uid, pid, len));
5426a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    }
5436a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<PidEntry> sortPids(uid_t uid, pid_t pid, size_t len, log_id id) {
5446a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<PidEntry>(pidSystemTable[id].sort(uid, pid, len));
545758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
5466a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn    LogFindWorst<TagEntry> sortTags(uid_t uid, pid_t pid, size_t len, log_id) {
5476a06694a610d103afdf424b0bb69dc8f7f2b8e5aMark Salyzyn        return LogFindWorst<TagEntry>(tagTable.sort(uid, pid, len));
548bec3c3def945576d59d3344c16e149e6d9154e15Mark Salyzyn    }
54934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
55034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // fast track current value by id only
55134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes(log_id_t id) const { return mSizes[id]; }
55234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements(log_id_t id) const { return mElements[id]; }
55358b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t realElements(log_id_t id) const {
55458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        return mElements[id] - mDroppedElements[id];
55558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
55697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
55797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
5583296291cffd13af13ea9e60a8ac1138101cf8e4cMark Salyzyn    static size_t sizesTotal() { return SizesTotal; }
55934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
560ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
5619a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
562ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn    // helper (must be locked directly or implicitly by mLogElementsLock)
563758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *pidToName(pid_t pid) const;
5644ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    uid_t pidToUid(pid_t pid);
565758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *uidToName(uid_t uid) const;
56634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
56734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
56834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__
569