LogStatistics.h revision ee3b838e13dc2140ac2051c1012d471effd0fd5f
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
284f71319df011d796a60a43fc1bc68e16fbf7d321Elliott Hughes#include <android-base/stringprintf.h>
2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/log.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) \
3634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    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
45720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynpublic:
46511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
47511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
48758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::const_iterator const_iterator;
49511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
50ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::unique_ptr<const TEntry *[]> sort(uid_t uid, pid_t pid,
51ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                           size_t len) const {
52758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!len) {
53720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            std::unique_ptr<const TEntry *[]> sorted(NULL);
54720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return sorted;
55720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
56720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
57758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        const TEntry **retval = new const TEntry* [len];
58758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        memset(retval, 0, sizeof(*retval) * len);
59720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
60758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for(const_iterator it = map.begin(); it != map.end(); ++it) {
61511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            const TEntry &entry = it->second;
62ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
63ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if ((uid != AID_ROOT) && (uid != entry.getUid())) {
64ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
65ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
66ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            if (pid && entry.getPid() && (pid != entry.getPid())) {
67ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                continue;
68ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            }
69ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
70758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            size_t sizes = entry.getSizes();
71758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            ssize_t index = len - 1;
72758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            while ((!retval[index] || (sizes > retval[index]->getSizes()))
73758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    && (--index >= 0))
74720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                ;
75758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (++index < (ssize_t)len) {
76758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                size_t num = len - index - 1;
77758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                if (num) {
78758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                    memmove(&retval[index + 1], &retval[index],
79758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                            num * sizeof(retval[0]));
80720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
81758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                retval[index] = &entry;
82720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
83720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
84720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const TEntry *[]> sorted(retval);
85720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return sorted;
86720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
87720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
88758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline iterator add(TKey key, LogBufferElement *element) {
89511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
90511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
91758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(element))).first;
92511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
93758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.add(element);
9481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
95511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
9681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
9781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
98511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator add(TKey key) {
99511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
100511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
101511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(key))).first;
102511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
103511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.add(key);
10481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
105511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
10681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
10781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
108758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    void subtract(TKey key, LogBufferElement *element) {
109511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
110758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if ((it != map.end()) && it->second.subtract(element)) {
111511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            map.erase(it);
11281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
11381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
11481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
115758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void drop(TKey key, LogBufferElement *element) {
116511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
117511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it != map.end()) {
118758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            it->second.drop(element);
11981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
12081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
12181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
122511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator begin() { return map.begin(); }
123758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline const_iterator begin() const { return map.begin(); }
124511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator end() { return map.end(); }
125758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline const_iterator end() const { return map.end(); }
126758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
127758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(
128758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const LogStatistics &stat,
129758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid_t uid,
130ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid_t pid,
131758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &name = std::string(""),
132758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            log_id_t id = LOG_ID_MAX) const {
133758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        static const size_t maximum_sorted_entries = 32;
134758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        std::string output;
135ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        std::unique_ptr<const TEntry *[]> sorted = sort(uid, pid,
136ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                                        maximum_sorted_entries);
137758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (!sorted.get()) {
138758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return output;
139758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
140758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        bool headerPrinted = false;
141758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        for (size_t index = 0; index < maximum_sorted_entries; ++index) {
142758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const TEntry *entry = sorted[index];
143758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!entry) {
144758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
145758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
146758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (entry->getSizes() <= (sorted[0]->getSizes() / 100)) {
147758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                break;
148758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
149758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            if (!headerPrinted) {
150758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += "\n\n";
151758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                output += entry->formatHeader(name, id);
152758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                headerPrinted = true;
153758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            }
154758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            output += entry->format(stat, id);
155758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
156758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return output;
157758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
158720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
159720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
160758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzynnamespace EntryBaseConstants {
161758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static constexpr size_t pruned_len = 14;
162758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static constexpr size_t total_len = 80;
163758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn}
164758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
16581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase {
16697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t size;
16734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
16881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase():size(0) { }
169758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    EntryBase(LogBufferElement *element):size(element->getMsgLen()) { }
17034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
17197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t getSizes() const { return size; }
17281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
173758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) { size += element->getMsgLen(); }
174758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline bool subtract(LogBufferElement *element) {
175758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        size -= element->getMsgLen();
176758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return !size;
177758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
178758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
179758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    static std::string formatLine(
180758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &name,
181758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &size,
182758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            const std::string &pruned) {
183758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        ssize_t drop_len = std::max(pruned.length() + 1,
184758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                    EntryBaseConstants::pruned_len);
185758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        ssize_t size_len = std::max(size.length() + 1,
186758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                    EntryBaseConstants::total_len
187758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                        - name.length() - drop_len - 1);
188758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
189758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (pruned.length()) {
190758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return android::base::StringPrintf("%s%*s%*s\n", name.c_str(),
191758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)size_len, size.c_str(),
192758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)drop_len, pruned.c_str());
193758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        } else {
194758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            return android::base::StringPrintf("%s%*s\n", name.c_str(),
195758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn                                               (int)size_len, size.c_str());
196758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        }
197758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
19881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
19981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
20081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase {
20181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t dropped;
20281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
20381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped():dropped(0) { }
204758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    EntryBaseDropped(LogBufferElement *element):
205758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBase(element),
206758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            dropped(element->getDropped()){
207758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
20881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
209ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t getDropped() const { return dropped; }
210ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
211758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
212758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped += element->getDropped();
213758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::add(element);
21481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
215758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline bool subtract(LogBufferElement *element) {
216758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        dropped -= element->getDropped();
217758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        return EntryBase::subtract(element) && !dropped;
21881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
219758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void drop(LogBufferElement *element) {
22081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += 1;
221758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::subtract(element);
22281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
22381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
22481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
22581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped {
22681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    const uid_t uid;
227ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
22881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
229758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    UidEntry(LogBufferElement *element):
230758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
231ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            uid(element->getUid()),
232ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()) {
233758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
23481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
23581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline const uid_t&getKey() const { return uid; }
236ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline const uid_t&getUid() const { return getKey(); }
237ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline const pid_t&getPid() const { return pid; }
238ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn
239ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    inline void add(LogBufferElement *element) {
240ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
241ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
242ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
243ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        EntryBase::add(element);
244ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    }
245758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
246758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
247758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
24834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
24934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
25081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android {
25181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid);
25281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}
25381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
25481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped {
255720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t pid;
256720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
257720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    char *name;
258720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
259758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    PidEntry(pid_t pid):
260758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(),
261758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(pid),
262758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(android::pidToUid(pid)),
263758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::pidToName(pid)) {
264758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
265758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    PidEntry(LogBufferElement *element):
266758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
267758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(element->getPid()),
268758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()),
269758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::pidToName(pid)) {
270758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
271758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    PidEntry(const PidEntry &element):
272758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
273758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            pid(element.pid),
274758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element.uid),
275758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(element.name ? strdup(element.name) : NULL) {
276758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
277720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ~PidEntry() { free(name); }
278720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
279720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t&getKey() const { return pid; }
280ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return getKey(); }
281720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const uid_t&getUid() const { return uid; }
282720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const char*getName() const { return name; }
28381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
284758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t newPid) {
285ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn        if (name && !fast<strncmp>(name, "zygote", 6)) {
286aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            free(name);
287aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            name = NULL;
288aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        }
28981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (!name) {
290758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(newPid);
29181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
29281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
29381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
294758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
295758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
296758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        if (getUid() != incomingUid) {
297758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
29881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            free(name);
299758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::pidToName(element->getPid());
30081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        } else {
301758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getPid());
30281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
303758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
30481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
305758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
306758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
307758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
308344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn};
309344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
31017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped {
31117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t tid;
312ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
31317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    uid_t uid;
31417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    char *name;
31517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
316ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    TidEntry(pid_t tid, pid_t pid):
317758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(),
318758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(tid),
319ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(pid),
320758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(android::pidToUid(tid)),
321758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::tidToName(tid)) {
322758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
323758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    TidEntry(LogBufferElement *element):
324758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
325758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(element->getTid()),
326ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()),
327758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()),
328758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(android::tidToName(tid)) {
329758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
330758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    TidEntry(const TidEntry &element):
331758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBaseDropped(element),
332758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tid(element.tid),
333ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element.pid),
334758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element.uid),
335758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name(element.name ? strdup(element.name) : NULL) {
336758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
33717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    ~TidEntry() { free(name); }
33817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
33917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t&getKey() const { return tid; }
340ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getTid() const { return getKey(); }
341ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return pid; }
34217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const uid_t&getUid() const { return uid; }
34317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const char*getName() const { return name; }
34417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
345758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(pid_t incomingTid) {
346ddda212faa81d62f637926680cd8163345120f71Mark Salyzyn        if (name && !fast<strncmp>(name, "zygote", 6)) {
34717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
34817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            name = NULL;
34917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
35017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (!name) {
351758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(incomingTid);
35217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
35317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
35417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
355758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
356758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        uid_t incomingUid = element->getUid();
357ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        pid_t incomingPid = element->getPid();
358ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if ((getUid() != incomingUid) || (getPid() != incomingPid)) {
359758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid = incomingUid;
360ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = incomingPid;
36117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
362758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            name = android::tidToName(element->getTid());
36317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        } else {
364758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            add(element->getTid());
36517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
366758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBaseDropped::add(element);
36717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
368758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
369758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
370758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
37117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn};
37217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
373344bff4391dd434dda501e812f18f524290c5a7cMark Salyzynstruct TagEntry : public EntryBase {
374344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t tag;
375ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    pid_t pid;
376344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    uid_t uid;
377344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
378758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    TagEntry(LogBufferElement *element):
379758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            EntryBase(element),
380758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            tag(element->getTag()),
381ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid(element->getPid()),
382758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn            uid(element->getUid()) {
383758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
384344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
385344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t&getKey() const { return tag; }
386ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    const pid_t&getPid() const { return pid; }
387344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uid_t&getUid() const { return uid; }
388344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const char*getName() const { return android::tagToName(tag); }
38981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
390758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    inline void add(LogBufferElement *element) {
391ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (uid != element->getUid()) {
392344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn            uid = -1;
393344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        }
394ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        if (pid != element->getPid()) {
395ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn            pid = -1;
396ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        }
397758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn        EntryBase::add(element);
398344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
399758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn
400758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string formatHeader(const std::string &name, log_id_t id) const;
401758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    std::string format(const LogStatistics &stat, log_id_t id) const;
402720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
403720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
40434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics
40534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics {
406c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn    friend UidEntry;
407c723df805a1a3199577cac947cebf2ab53abdb34Mark Salyzyn
40834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mSizes[LOG_ID_MAX];
40934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mElements[LOG_ID_MAX];
41058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t mDroppedElements[LOG_ID_MAX];
41197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mSizesTotal[LOG_ID_MAX];
41297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mElementsTotal[LOG_ID_MAX];
413720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    bool enable;
41434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
41597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // uid to size list
416720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
41797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t uidTable[LOG_ID_MAX];
418e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
419720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // pid to uid list
420720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
421720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pidTable_t pidTable;
422720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
42317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    // tid to uid list
42417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    typedef LogHashtable<pid_t, TidEntry> tidTable_t;
42517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    tidTable_t tidTable;
42617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
427344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    // tag list
428344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
429344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    tagTable_t tagTable;
430344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
431083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    // security tag list
432083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn    tagTable_t securityTagTable;
433083b037c0740ca00f72429e4457bfdd4b4d4dfa7Mark Salyzyn
43434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic:
43534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    LogStatistics();
43634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
437720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    void enableStatistics() { enable = true; }
43834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
43997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void add(LogBufferElement *entry);
44097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void subtract(LogBufferElement *entry);
441ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // entry->setDropped(1) must follow this call
442ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void drop(LogBufferElement *entry);
443aaad42f47c7363d68ddfb9ef8f1b51972c4d429dMark Salyzyn    // Correct for coalescing two entries referencing dropped content
44458b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    void erase(LogBufferElement *element) {
44558b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        log_id_t log_id = element->getLogId();
44658b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mElements[log_id];
44758b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        --mDroppedElements[log_id];
44858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
449e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
450ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::unique_ptr<const UidEntry *[]> sort(uid_t uid, pid_t pid,
451ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn                                             size_t len, log_id id) {
452ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn        return uidTable[id].sort(uid, pid, len);
453758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    }
45434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
45534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // fast track current value by id only
45634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes(log_id_t id) const { return mSizes[id]; }
45734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements(log_id_t id) const { return mElements[id]; }
45858b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    size_t realElements(log_id_t id) const {
45958b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn        return mElements[id] - mDroppedElements[id];
46058b8be8906f903ac3d83c41bcb0fb9c7841945f0Mark Salyzyn    }
46197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
46297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
46334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
464ee3b838e13dc2140ac2051c1012d471effd0fd5fMark Salyzyn    std::string format(uid_t uid, pid_t pid, unsigned int logMask) const;
4659a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
466ed777e9eece54bf899f1a77a83f8b702970de686Mark Salyzyn    // helper (must be locked directly or implicitly by mLogElementsLock)
467758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *pidToName(pid_t pid) const;
4684ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    uid_t pidToUid(pid_t pid);
469758058ffd8820df71c27db7675c50a90a5fa02b4Mark Salyzyn    const char *uidToName(uid_t uid) const;
47034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
47134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
47234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__
473