LogStatistics.h revision 511338dd575572d567c04d69eaea60627b6c3452
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
24511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn#include <unordered_map>
25511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
2634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/log.h>
2797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
2897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include "LogBufferElement.h"
2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
3034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define log_id_for_each(i) \
3134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1))
3234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
33720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyntemplate <typename TKey, typename TEntry>
34511338dd575572d567c04d69eaea60627b6c3452Mark Salyzynclass LogHashtable {
35511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
36511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    std::unordered_map<TKey, TEntry> map;
37511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
38720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynpublic:
39511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
40511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    typedef typename std::unordered_map<TKey, TEntry>::iterator iterator;
41511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
42720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    std::unique_ptr<const TEntry *[]> sort(size_t n) {
43720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (!n) {
44720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            std::unique_ptr<const TEntry *[]> sorted(NULL);
45720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return sorted;
46720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
47720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
48720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        const TEntry **retval = new const TEntry* [n];
49720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        memset(retval, 0, sizeof(*retval) * n);
50720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
51511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        for(iterator it = map.begin(); it != map.end(); ++it) {
52511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            const TEntry &entry = it->second;
53720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            size_t s = entry.getSizes();
54720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            ssize_t i = n - 1;
55720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            while ((!retval[i] || (s > retval[i]->getSizes())) && (--i >= 0))
56720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                ;
57720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (++i < (ssize_t)n) {
58720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                size_t b = n - i - 1;
59720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (b) {
60720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    memmove(&retval[i+1], &retval[i], b * sizeof(retval[0]));
61720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
62720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                retval[i] = &entry;
63720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
64720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
65720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const TEntry *[]> sorted(retval);
66720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return sorted;
67720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
68720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
69720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // Iteration handler for the sort method output
70720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    static ssize_t next(ssize_t index, std::unique_ptr<const TEntry *[]> &sorted, size_t n) {
71720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        ++index;
72720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (!sorted.get() || (index < 0) || (n <= (size_t)index) || !sorted[index]
73720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn         || (sorted[index]->getSizes() <= (sorted[0]->getSizes() / 100))) {
74720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return -1;
75720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
76720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return index;
77720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
78720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
79511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator add(TKey key, LogBufferElement *e) {
80511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
81511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
82511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(e))).first;
83511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
84511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.add(e);
8581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
86511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
8781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
8881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
89511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator add(TKey key) {
90511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
91511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it == map.end()) {
92511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it = map.insert(std::make_pair(key, TEntry(key))).first;
93511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        } else {
94511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.add(key);
9581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
96511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        return it;
9781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
9881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
9981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    void subtract(TKey key, LogBufferElement *e) {
100511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
101511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if ((it != map.end()) && it->second.subtract(e)) {
102511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            map.erase(it);
10381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
10481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
10581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
10681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void drop(TKey key, LogBufferElement *e) {
107511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        iterator it = map.find(key);
108511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn        if (it != map.end()) {
109511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn            it->second.drop(e);
11081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
11181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
11281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
113511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator begin() { return map.begin(); }
114511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn    inline iterator end() { return map.end(); }
115511338dd575572d567c04d69eaea60627b6c3452Mark Salyzyn
116720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
117720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
11881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase {
11997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t size;
12034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
12181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase():size(0) { }
12281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase(LogBufferElement *e):size(e->getMsgLen()) { }
12334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
12497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t getSizes() const { return size; }
12581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
12681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(LogBufferElement *e) { size += e->getMsgLen(); }
12781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline bool subtract(LogBufferElement *e) { size -= e->getMsgLen(); return !size; }
12881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
12981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
13081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase {
13181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t dropped;
13281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
13381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped():dropped(0) { }
13481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped(LogBufferElement *e):EntryBase(e),dropped(e->getDropped()){ }
13581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
136ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t getDropped() const { return dropped; }
137ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
13881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(LogBufferElement *e) {
13981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += e->getDropped();
14081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBase::add(e);
14181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
14281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline bool subtract(LogBufferElement *e) {
14381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped -= e->getDropped();
14481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        return EntryBase::subtract(e) && !dropped;
14581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
14681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void drop(LogBufferElement *e) {
14781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += 1;
14881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBase::subtract(e);
14981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
15081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
15181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
15281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped {
15381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    const uid_t uid;
15481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
15581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    UidEntry(LogBufferElement *e):EntryBaseDropped(e),uid(e->getUid()) { }
15681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
15781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline const uid_t&getKey() const { return uid; }
15834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
15934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
16081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android {
16181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid);
16281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}
16381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
16481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped {
165720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t pid;
166720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
167720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    char *name;
168720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
16981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    PidEntry(pid_t p):
17081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped(),
17181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        pid(p),
17281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        uid(android::pidToUid(p)),
17381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        name(android::pidToName(pid)) { }
17481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    PidEntry(LogBufferElement *e):
17581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped(e),
17681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        pid(e->getPid()),
17781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        uid(e->getUid()),
17881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        name(android::pidToName(e->getPid())) { }
179720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    PidEntry(const PidEntry &c):
18081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped(c),
181720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        pid(c.pid),
182720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        uid(c.uid),
18381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        name(c.name ? strdup(c.name) : NULL) { }
184720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ~PidEntry() { free(name); }
185720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
186720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t&getKey() const { return pid; }
187720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const uid_t&getUid() const { return uid; }
188720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const char*getName() const { return name; }
18981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
19081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(pid_t p) {
191aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        if (name && !strncmp(name, "zygote", 6)) {
192aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            free(name);
193aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            name = NULL;
194aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        }
19581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (!name) {
19681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            char *n = android::pidToName(p);
19781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            if (n) {
19881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn                name = n;
19981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            }
20081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
20181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
20281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
20381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(LogBufferElement *e) {
20481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        uid_t u = e->getUid();
20581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (getUid() != u) {
20681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            uid = u;
20781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            free(name);
20881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            name = android::pidToName(e->getPid());
20981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        } else {
21081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            add(e->getPid());
21181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
21281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped::add(e);
21381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
214344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn};
215344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
21617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzynstruct TidEntry : public EntryBaseDropped {
21717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t tid;
21817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    uid_t uid;
21917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    char *name;
22017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
22117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    TidEntry(pid_t t):
22217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        EntryBaseDropped(),
22317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        tid(t),
22417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        uid(android::pidToUid(t)),
22517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        name(android::tidToName(tid)) { }
22617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    TidEntry(LogBufferElement *e):
22717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        EntryBaseDropped(e),
22817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        tid(e->getTid()),
22917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        uid(e->getUid()),
23017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        name(android::tidToName(e->getTid())) { }
23117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    TidEntry(const TidEntry &c):
23217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        EntryBaseDropped(c),
23317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        tid(c.tid),
23417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        uid(c.uid),
23517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        name(c.name ? strdup(c.name) : NULL) { }
23617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    ~TidEntry() { free(name); }
23717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
23817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const pid_t&getKey() const { return tid; }
23917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const uid_t&getUid() const { return uid; }
24017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    const char*getName() const { return name; }
24117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
24217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    inline void add(pid_t t) {
24317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (name && !strncmp(name, "zygote", 6)) {
24417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
24517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            name = NULL;
24617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
24717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (!name) {
24817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            char *n = android::tidToName(t);
24917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            if (n) {
25017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn                name = n;
25117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            }
25217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
25317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
25417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
25517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    inline void add(LogBufferElement *e) {
25617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        uid_t u = e->getUid();
25717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        if (getUid() != u) {
25817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            uid = u;
25917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            free(name);
26017ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            name = android::tidToName(e->getTid());
26117ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        } else {
26217ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn            add(e->getTid());
26317ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        }
26417ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn        EntryBaseDropped::add(e);
26517ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    }
26617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn};
26717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
268344bff4391dd434dda501e812f18f524290c5a7cMark Salyzynstruct TagEntry : public EntryBase {
269344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t tag;
270344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    uid_t uid;
271344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
272344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    TagEntry(LogBufferElement *e):
273344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        EntryBase(e),
274344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        tag(e->getTag()),
275344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        uid(e->getUid()) { }
276344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
277344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uint32_t&getKey() const { return tag; }
278344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const uid_t&getUid() const { return uid; }
279344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    const char*getName() const { return android::tagToName(tag); }
28081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
281344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    inline void add(LogBufferElement *e) {
282344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        uid_t u = e->getUid();
283344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        if (uid != u) {
284344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn            uid = -1;
285344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        }
286344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn        EntryBase::add(e);
287344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    }
288720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
289720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
29034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics
29134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics {
29234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mSizes[LOG_ID_MAX];
29334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mElements[LOG_ID_MAX];
29497c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mSizesTotal[LOG_ID_MAX];
29597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mElementsTotal[LOG_ID_MAX];
296720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    bool enable;
29734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
29897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // uid to size list
299720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
30097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t uidTable[LOG_ID_MAX];
301e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
302720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // pid to uid list
303720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
304720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pidTable_t pidTable;
305720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
30617ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    // tid to uid list
30717ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    typedef LogHashtable<pid_t, TidEntry> tidTable_t;
30817ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn    tidTable_t tidTable;
30917ed6797df722464eb5cc6dfc3e1e32aec284b70Mark Salyzyn
310344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    // tag list
311344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    typedef LogHashtable<uint32_t, TagEntry> tagTable_t;
312344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn    tagTable_t tagTable;
313344bff4391dd434dda501e812f18f524290c5a7cMark Salyzyn
31434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic:
31534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    LogStatistics();
31634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
317720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    void enableStatistics() { enable = true; }
31834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
31997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void add(LogBufferElement *entry);
32097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void subtract(LogBufferElement *entry);
321ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // entry->setDropped(1) must follow this call
322ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void drop(LogBufferElement *entry);
323ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // Correct for merging two entries referencing dropped content
324ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void erase(LogBufferElement *e) { --mElements[e->getLogId()]; }
325e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
326720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    std::unique_ptr<const UidEntry *[]> sort(size_t n, log_id i) { return uidTable[i].sort(n); }
32734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
32834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // fast track current value by id only
32934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes(log_id_t id) const { return mSizes[id]; }
33034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements(log_id_t id) const { return mElements[id]; }
33197c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
33297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
33334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
33434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // *strp = malloc, balance with free
33597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void format(char **strp, uid_t uid, unsigned int logMask);
3369a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
3379a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    // helper
33897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char *pidToName(pid_t pid);
3394ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    uid_t pidToUid(pid_t pid);
34097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char *uidToName(uid_t uid);
34134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
34234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
34334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__
344