120 lines
3.1 KiB
C
120 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2020 Tobias Brunner
|
|
* HSR Hochschule fuer Technik Rapperswil
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*/
|
|
|
|
#ifndef HASHTABLE_PROFILER_H_
|
|
#define HASHTABLE_PROFILER_H_
|
|
|
|
#ifdef HASHTABLE_PROFILER
|
|
|
|
#include <time.h>
|
|
#include <utils/backtrace.h>
|
|
|
|
typedef struct hashtable_profile_t hashtable_profile_t;
|
|
|
|
struct hashtable_profile_t {
|
|
|
|
/**
|
|
* Some stats to profile lookups in the table
|
|
*/
|
|
struct {
|
|
size_t count;
|
|
size_t probes;
|
|
size_t longest;
|
|
} success, failure;
|
|
|
|
/**
|
|
* Stats on the memory usage of the table
|
|
*/
|
|
struct {
|
|
size_t count;
|
|
size_t size;
|
|
} max;
|
|
|
|
/**
|
|
* Keep track of where the hash table was created
|
|
*/
|
|
backtrace_t *backtrace;
|
|
};
|
|
|
|
/**
|
|
* Print and cleanup profiling data
|
|
*/
|
|
static inline void profiler_cleanup(hashtable_profile_t *profile, u_int count,
|
|
u_int size)
|
|
{
|
|
if (profile->success.count || profile->failure.count)
|
|
{
|
|
fprintf(stderr, "%zu elements [max. %zu], %zu buckets [%zu], %zu "
|
|
"successful / %zu failed lookups, %.4f [%zu] / %.4f "
|
|
"[%zu] avg. probes in table created at:",
|
|
count, profile->max.count, size, profile->max.size,
|
|
profile->success.count, profile->failure.count,
|
|
(double)profile->success.probes/profile->success.count,
|
|
profile->success.longest,
|
|
(double)profile->failure.probes/profile->failure.count,
|
|
profile->failure.longest);
|
|
profile->backtrace->log(profile->backtrace, stderr, TRUE);
|
|
}
|
|
profile->backtrace->destroy(profile->backtrace);
|
|
}
|
|
|
|
/**
|
|
* Initialize profiling data
|
|
*/
|
|
static inline void profiler_init(hashtable_profile_t *profile, int skip)
|
|
{
|
|
profile->backtrace = backtrace_create(skip);
|
|
}
|
|
|
|
#define lookup_start() \
|
|
u_int _lookup_probes = 0;
|
|
|
|
#define lookup_probing() \
|
|
_lookup_probes++;
|
|
|
|
#define _lookup_done(profile, result) \
|
|
(profile)->result.count++; \
|
|
(profile)->result.probes += _lookup_probes; \
|
|
(profile)->result.longest = max((profile)->result.longest, _lookup_probes);
|
|
|
|
#define lookup_success(profile) _lookup_done(profile, success);
|
|
#define lookup_failure(profile) _lookup_done(profile, failure);
|
|
|
|
static inline void profile_size(hashtable_profile_t *profile, u_int size)
|
|
{
|
|
profile->max.size = max(profile->max.size, size);
|
|
}
|
|
|
|
static inline void profile_count(hashtable_profile_t *profile, u_int count)
|
|
{
|
|
profile->max.count = max(profile->max.count, count);
|
|
}
|
|
|
|
#else /* !HASHTABLE_PROFILER */
|
|
|
|
#define hashtable_profile_t struct {}
|
|
#define profiler_cleanup(...) {}
|
|
#define profiler_init(...) {}
|
|
#define lookup_start(...) {}
|
|
#define lookup_probing(...) {}
|
|
#define lookup_success(...) {}
|
|
#define lookup_failure(...) {}
|
|
#define profile_size(...) {}
|
|
#define profile_count(...) {}
|
|
|
|
#endif /* HASHTABLE_PROFILER */
|
|
|
|
#endif /* HASHTABLE_PROFILER_H_ */
|