diff options
Diffstat (limited to 'debian/htdig/htdig-3.2.0b6/htword/WordMonitor.cc')
-rw-r--r-- | debian/htdig/htdig-3.2.0b6/htword/WordMonitor.cc | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/debian/htdig/htdig-3.2.0b6/htword/WordMonitor.cc b/debian/htdig/htdig-3.2.0b6/htword/WordMonitor.cc new file mode 100644 index 00000000..d5f342fd --- /dev/null +++ b/debian/htdig/htdig-3.2.0b6/htword/WordMonitor.cc @@ -0,0 +1,272 @@ +// +// WordMonitor.cc +// +// Part of the ht://Dig package <http://www.htdig.org/> +// Copyright (c) 1999-2004 The ht://Dig Group +// For copyright details, see the file COPYING in your distribution +// or the GNU Library General Public License (LGPL) version 2 or later +// <http://www.gnu.org/copyleft/lgpl.html> +// +// $Id: WordMonitor.cc,v 1.7 2004/05/28 13:15:28 lha Exp $ +// + +#ifdef HAVE_CONFIG_H +#include "htconfig.h" +#endif /* HAVE_CONFIG_H */ + +#include <stdlib.h> +#include <signal.h> + +#ifndef _MSC_VER /* _WIN32 */ +#include <unistd.h> +#endif + +#include "StringList.h" +#include "WordMonitor.h" + +#define WORD_MONITOR_RRD 1 +#define WORD_MONITOR_READABLE 2 + +WordMonitor* WordMonitor::instance = 0; + +char* WordMonitor::values_names[WORD_MONITOR_VALUES_SIZE] = { + "", + "C.Write", + "C.Read", + "C.Compress 1/1", + "C.Compress 1/2", + "C.Compress 1/3", + "C.Compress 1/4", + "C.Compress 1/5", + "C.Compress 1/6", + "C.Compress 1/7", + "C.Compress 1/8", + "C.Compress 1/9", + "C.Compress 1/10", + "C.Compress 1/>10", + "C.P_IBTREE", + "C.P_LBTREE", + "C.P_UNKNOWN", + "C.Put", + "C.Get (0)", + "C.Get (NEXT)", + "C.Get (SET_RANGE)", + "C.Get (Other)", + "G.LEVEL", + "G.PGNO", + "C.CMP", + 0 +}; + +WordMonitor::WordMonitor(const Configuration &config) +{ + memset((char*)values, '\0', sizeof(unsigned int) * WORD_MONITOR_VALUES_SIZE); + memset((char*)old_values, '\0', sizeof(unsigned int) * WORD_MONITOR_VALUES_SIZE); + started = elapsed = time(0); + output_style = WORD_MONITOR_READABLE; + if((period = config.Value("wordlist_monitor_period"))) { + const String& desc = config.Find("wordlist_monitor_output"); + StringList fields(desc, ','); + + if(fields.Count() > 0) { + char* filename = fields[0]; + if(filename[0] == '\0') + output = stderr; + else { + output = fopen(filename, "a"); + if(!output) { + fprintf(stderr, "WordMonitor::WordMonitor: cannot open %s for writing ", filename); + perror(""); + output = stderr; + return; + } + } + if(fields.Count() > 1) { + char* style = fields[1]; + if(!mystrcasecmp(style, "rrd")) + output_style = WORD_MONITOR_RRD; + else + output_style = WORD_MONITOR_READABLE; + } + } + TimerStart(); + } +} + +WordMonitor::~WordMonitor() +{ + TimerStop(); + if(output != stderr) + fclose(output); +} + +void +WordMonitor::Initialize(const Configuration &config_arg) +{ + if(instance != 0) + delete instance; + instance = new WordMonitor(config_arg); +} + +const String +WordMonitor::Report() const +{ + String output; + int i; + time_t now = time(0); + + if(output_style == WORD_MONITOR_RRD) + output << (int)now << ":"; + + for(i = 0; i < WORD_MONITOR_VALUES_SIZE; i++) { + if(!values_names[i]) break; + if(values_names[i][0]) { + if(output_style == WORD_MONITOR_READABLE) { + output << values_names[i] << ": " << values[i]; + if((now - elapsed) > 0) { + output << ", per sec : " << (int)(values[i] / (now - started)); + output << ", delta : " << (values[i] - old_values[i]); + output << ", per sec : " << (int)((values[i] - old_values[i]) / (now - elapsed)); + } + output << "|"; + } else if(output_style == WORD_MONITOR_RRD) { + output << values[i] << ":"; + } + } + } + memcpy((char*)old_values, (char*)values, sizeof(unsigned int) * WORD_MONITOR_VALUES_SIZE); + return output; +} + +static void handler_alarm(int signal) +{ + WordMonitor* monitor = WordMonitor::Instance(); + if(!monitor) { + fprintf(stderr, "WordMonitor::handler_alarm: no instance\n"); + return; + } + monitor->TimerClick(signal); +} + +void +WordMonitor::TimerStart() +{ + if(period < 5) { + fprintf(stderr, "WordMonitor::TimerStart: wordlist_monitor_period must be > 5 (currently %d) otherwise monitoring is not accurate\n", period); + return; + } + +#ifndef _MSC_VER /* _WIN32 */ + struct sigaction action; + struct sigaction old_action; + memset((char*)&action, '\0', sizeof(struct sigaction)); + memset((char*)&old_action, '\0', sizeof(struct sigaction)); + action.sa_handler = handler_alarm; + if(sigaction(SIGALRM, &action, &old_action) != 0) { + fprintf(stderr, "WordMonitor::TimerStart: installing SIGALRM "); + perror(""); + } + + if(old_action.sa_handler != SIG_DFL) { + fprintf(stderr, "WordMonitor::TimerStart: found an installed action while installing SIGALRM, restoring old action\n"); + if(sigaction(SIGALRM, &old_action, NULL) != 0) { + fprintf(stderr, "WordMonitor::TimerStart: installing old SIGALRM "); + perror(""); + } + return; + } +#endif + + fprintf(output, "----------------- WordMonitor starting -------------------\n"); + if(output_style == WORD_MONITOR_RRD) { + fprintf(output, "Started:%ld\n", started); + fprintf(output, "Period:%d\n", period); + fprintf(output, "Time:"); + int i; + for(i = 0; i < WORD_MONITOR_VALUES_SIZE; i++) { + if(!values_names[i]) break; + if(values_names[i][0]) + fprintf(output, "%s:", values_names[i]); + } + fprintf(output, "\n"); + } + fflush(output); + TimerClick(0); +} + +void +WordMonitor::TimerClick(int signal) +{ + if(signal) { + // + // Do not report if less than <period> since last report. + // + if(time(0) - elapsed >= period) { + fprintf(output, "%s\n", (const char*)Report()); + elapsed = time(0); + fflush(output); + } + } +#ifndef _MSC_VER /* _WIN32 */ + alarm(period); +#endif +} + +void +WordMonitor::TimerStop() +{ + if(period > 0) { +#ifndef _MSC_VER /* _WIN32 */ + alarm(0); + struct sigaction action; + memset((char*)&action, '\0', sizeof(struct sigaction)); + action.sa_handler = SIG_DFL; + if(sigaction(SIGALRM, &action, NULL) != 0) { + fprintf(stderr, "WordMonitor::TimerStart: resetting SIGALRM to SIG_DFL "); + perror(""); + } + + // Make sure last report is at least one second older than the previous one. + // + if(time(0) - elapsed < 1) + sleep(2); + fprintf(output, "%s\n", (const char*)Report()); + fprintf(output, "----------------- WordMonitor finished -------------------\n"); +#endif + } +} + +// +// C interface to WordMonitor instance +// + +extern "C" { + void word_monitor_click() + { + WordMonitor* monitor = WordMonitor::Instance(); +#ifndef _MSC_VER /* _WIN32 */ + if(monitor) + monitor->TimerClick(SIGALRM); +#endif + } + void word_monitor_add(int index, unsigned int value) + { + WordMonitor* monitor = WordMonitor::Instance(); + if(monitor) + monitor->Add(index, value); + } + void word_monitor_set(int index, unsigned int value) + { + WordMonitor* monitor = WordMonitor::Instance(); + if(monitor) + monitor->Set(index, value); + } + unsigned int word_monitor_get(int index) + { + WordMonitor* monitor = WordMonitor::Instance(); + if(monitor) + return monitor->Get(index); + else + return 0; + } +} |