LogStatistics.h revision aa43ae2268076227e8b72ea095f8aeac439b3168
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
2434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#include <log/log.h>
2597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include <utils/BasicHashtable.h>
2697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn
2797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn#include "LogBufferElement.h"
2834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
2934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#define log_id_for_each(i) \
3034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    for (log_id_t i = LOG_ID_MIN; i < LOG_ID_MAX; i = (log_id_t) (i + 1))
3134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
32720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyntemplate <typename TKey, typename TEntry>
33720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynclass LogHashtable : public android::BasicHashtable<TKey, TEntry> {
34720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzynpublic:
35720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    std::unique_ptr<const TEntry *[]> sort(size_t n) {
36720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (!n) {
37720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            std::unique_ptr<const TEntry *[]> sorted(NULL);
38720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return sorted;
39720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
40720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
41720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        const TEntry **retval = new const TEntry* [n];
42720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        memset(retval, 0, sizeof(*retval) * n);
43720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
44720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        ssize_t index = -1;
45720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        while ((index = android::BasicHashtable<TKey, TEntry>::next(index)) >= 0) {
46720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            const TEntry &entry = android::BasicHashtable<TKey, TEntry>::entryAt(index);
47720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            size_t s = entry.getSizes();
48720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            ssize_t i = n - 1;
49720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            while ((!retval[i] || (s > retval[i]->getSizes())) && (--i >= 0))
50720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                ;
51720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            if (++i < (ssize_t)n) {
52720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                size_t b = n - i - 1;
53720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                if (b) {
54720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                    memmove(&retval[i+1], &retval[i], b * sizeof(retval[0]));
55720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                }
56720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn                retval[i] = &entry;
57720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            }
58720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
59720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        std::unique_ptr<const TEntry *[]> sorted(retval);
60720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return sorted;
61720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
62720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
63720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // Iteration handler for the sort method output
64720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    static ssize_t next(ssize_t index, std::unique_ptr<const TEntry *[]> &sorted, size_t n) {
65720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        ++index;
66720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        if (!sorted.get() || (index < 0) || (n <= (size_t)index) || !sorted[index]
67720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn         || (sorted[index]->getSizes() <= (sorted[0]->getSizes() / 100))) {
68720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn            return -1;
69720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        }
70720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return index;
71720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
72720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
73720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ssize_t next(ssize_t index) {
74720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        return android::BasicHashtable<TKey, TEntry>::next(index);
75720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    }
7681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
7781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t add(TKey key, LogBufferElement *e) {
7881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        android::hash_t hash = android::hash_type(key);
7981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
8081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (index == -1) {
8181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(e));
8281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
8381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(e);
8481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        return index;
8581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
8681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
8781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline size_t add(TKey key) {
8881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        android::hash_t hash = android::hash_type(key);
8981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, hash, key);
9081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (index == -1) {
9181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            return android::BasicHashtable<TKey, TEntry>::add(hash, TEntry(key));
9281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
9381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        android::BasicHashtable<TKey, TEntry>::editEntryAt(index).add(key);
9481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        return index;
9581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
9681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
9781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    void subtract(TKey key, LogBufferElement *e) {
9881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
9981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if ((index != -1)
10081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn         && android::BasicHashtable<TKey, TEntry>::editEntryAt(index).subtract(e)) {
10181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            android::BasicHashtable<TKey, TEntry>::removeAt(index);
10281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
10381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
10481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
10581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void drop(TKey key, LogBufferElement *e) {
10681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        ssize_t index = android::BasicHashtable<TKey, TEntry>::find(-1, android::hash_type(key), key);
10781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (index != -1) {
10881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            android::BasicHashtable<TKey, TEntry>::editEntryAt(index).drop(e);
10981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
11081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
11181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
112720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
113720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
11481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBase {
11597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t size;
11634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
11781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase():size(0) { }
11881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBase(LogBufferElement *e):size(e->getMsgLen()) { }
11934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
12097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t getSizes() const { return size; }
12181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
12281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(LogBufferElement *e) { size += e->getMsgLen(); }
12381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline bool subtract(LogBufferElement *e) { size -= e->getMsgLen(); return !size; }
12481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
12581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
12681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct EntryBaseDropped : public EntryBase {
12781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    size_t dropped;
12881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
12981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped():dropped(0) { }
13081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    EntryBaseDropped(LogBufferElement *e):EntryBase(e),dropped(e->getDropped()){ }
13181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
132ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    size_t getDropped() const { return dropped; }
133ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn
13481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(LogBufferElement *e) {
13581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += e->getDropped();
13681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBase::add(e);
13781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
13881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline bool subtract(LogBufferElement *e) {
13981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped -= e->getDropped();
14081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        return EntryBase::subtract(e) && !dropped;
14181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
14281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void drop(LogBufferElement *e) {
14381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        dropped += 1;
14481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBase::subtract(e);
14581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
14681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn};
14781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
14881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct UidEntry : public EntryBaseDropped {
14981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    const uid_t uid;
15081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
15181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    UidEntry(LogBufferElement *e):EntryBaseDropped(e),uid(e->getUid()) { }
15281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
15381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline const uid_t&getKey() const { return uid; }
15434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
15534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
15681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynnamespace android {
15781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn// caller must own and free character string
15881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynchar *pidToName(pid_t pid);
15981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynuid_t pidToUid(pid_t pid);
16081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn}
16181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
16281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzynstruct PidEntry : public EntryBaseDropped {
163720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t pid;
164720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    uid_t uid;
165720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    char *name;
166720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
16781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    PidEntry(pid_t p):
16881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped(),
16981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        pid(p),
17081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        uid(android::pidToUid(p)),
17181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        name(android::pidToName(pid)) { }
17281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    PidEntry(LogBufferElement *e):
17381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped(e),
17481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        pid(e->getPid()),
17581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        uid(e->getUid()),
17681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        name(android::pidToName(e->getPid())) { }
177720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    PidEntry(const PidEntry &c):
17881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped(c),
179720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        pid(c.pid),
180720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn        uid(c.uid),
18181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        name(c.name ? strdup(c.name) : NULL) { }
182720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    ~PidEntry() { free(name); }
183720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
184720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const pid_t&getKey() const { return pid; }
185720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const uid_t&getUid() const { return uid; }
186720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    const char*getName() const { return name; }
18781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
18881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(pid_t p) {
189aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        if (name && !strncmp(name, "zygote", 6)) {
190aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            free(name);
191aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn            name = NULL;
192aa43ae2268076227e8b72ea095f8aeac439b3168Mark Salyzyn        }
19381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (!name) {
19481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            char *n = android::pidToName(p);
19581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            if (n) {
19681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn                name = n;
19781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            }
19881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
19981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
20081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
20181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    inline void add(LogBufferElement *e) {
20281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        uid_t u = e->getUid();
20381b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        if (getUid() != u) {
20481b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            uid = u;
20581b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            free(name);
20681b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            name = android::pidToName(e->getPid());
20781b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        } else {
20881b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn            add(e->getPid());
20981b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        }
21081b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn        EntryBaseDropped::add(e);
21181b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn    }
21281b3eabc49736b89c4f99940f79785074955eaa5Mark Salyzyn
213720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn};
214720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
21534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn// Log Statistics
21634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynclass LogStatistics {
21734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mSizes[LOG_ID_MAX];
21834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t mElements[LOG_ID_MAX];
21997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mSizesTotal[LOG_ID_MAX];
22097c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t mElementsTotal[LOG_ID_MAX];
221720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    bool enable;
22234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
22397c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    // uid to size list
224720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<uid_t, UidEntry> uidTable_t;
22597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    uidTable_t uidTable[LOG_ID_MAX];
226e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
227720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    // pid to uid list
228720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    typedef LogHashtable<pid_t, PidEntry> pidTable_t;
229720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    pidTable_t pidTable;
230720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn
23134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzynpublic:
23234facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    LogStatistics();
23334facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
234720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    void enableStatistics() { enable = true; }
23534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
23697c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void add(LogBufferElement *entry);
23797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void subtract(LogBufferElement *entry);
238ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // entry->setDropped(1) must follow this call
239ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void drop(LogBufferElement *entry);
240ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    // Correct for merging two entries referencing dropped content
241ab0dcf682867bd7e1fdebfd8d8f9fafaccfad7f6Mark Salyzyn    void erase(LogBufferElement *e) { --mElements[e->getLogId()]; }
242e457b74ce6ee6d799812dc2ec5e4b8b18bcd3e91Mark Salyzyn
243720f6d1d55d936d98cc9752e96f479e03e6d5009Mark Salyzyn    std::unique_ptr<const UidEntry *[]> sort(size_t n, log_id i) { return uidTable[i].sort(n); }
24434facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
24534facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // fast track current value by id only
24634facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t sizes(log_id_t id) const { return mSizes[id]; }
24734facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    size_t elements(log_id_t id) const { return mElements[id]; }
24897c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t sizesTotal(log_id_t id) const { return mSizesTotal[id]; }
24997c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    size_t elementsTotal(log_id_t id) const { return mElementsTotal[id]; }
25034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
25134facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn    // *strp = malloc, balance with free
25297c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    void format(char **strp, uid_t uid, unsigned int logMask);
2539a03863e88da99ba010342c874252089dd771f7fMark Salyzyn
2549a03863e88da99ba010342c874252089dd771f7fMark Salyzyn    // helper
25597c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char *pidToName(pid_t pid);
2564ba0387af5acc52e43e4004ccb4c46b8bc700349Mark Salyzyn    uid_t pidToUid(pid_t pid);
25797c1c2beee2cbd8c67c1cd507367e5b084d853c8Mark Salyzyn    char *uidToName(uid_t uid);
25834facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn};
25934facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn
26034facab86b0fe7ec613de92b46b637f864fb0682Mark Salyzyn#endif // _LOGD_LOG_STATISTICS_H__
261