windows-nt/Source/XPSP1/NT/enduser/troubleshoot/tshoot/counter.h
2020-09-26 16:20:57 +08:00

413 lines
13 KiB
C++

//
// MODULE: COUNTER.H
//
// PURPOSE: interface for the counter classes:
// CPeriodicTotals (utility class)
// CAbstractCounter (abstract base class).
// CCounter (simple counter)
// CHourlyCounter (counter with "bins" for each hour of the day)
// CDailyCounter (counter with "bins" for day of the week)
// CHourlyDailyCounter (counter with "bins" for each hour of the day and each day of the week)
//
// PROJECT: Generic Troubleshooter DLL for Microsoft AnswerPoint
//
// COMPANY: Saltmine Creative, Inc. (206)-284-7511 support@saltmine.com
//
// AUTHOR: Joe Mabel
// MODIFIED: Oleg Kalosha 10-20-98
//
// ORIGINAL DATE: 7-20-1998
//
// NOTES:
// 1. CPeriodicTotals might better be implemented using STL vectors. We wrote this
// before we really started bringing STL into this application. JM 10/98
//
// Version Date By Comments
//--------------------------------------------------------------------
// V3.0 7-20-98 JM Original
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_COUNTER_H__07B5ABBD_2005_11D2_95D0_00C04FC22ADD__INCLUDED_)
#define AFX_COUNTER_H__07B5ABBD_2005_11D2_95D0_00C04FC22ADD__INCLUDED_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include <time.h>
#include "apgtsstr.h"
////////////////////////////////////////////////////////////////////////////////////
// a utility class to allow the expression of a series of time periods & associated counts
////////////////////////////////////////////////////////////////////////////////////
class CPeriodicTotals
{
public:
CPeriodicTotals(long nPeriods);
virtual ~CPeriodicTotals();
void Reset();
bool SetNext(time_t time, long Count);
private:
void ReleaseMem();
protected:
CString & DisplayPeriod(long i, CString & str) const;
public:
virtual CString HTMLDisplay() const = 0;
protected:
long m_nPeriods; // number of periods, based on initialization in constructor.
// typically 25 (hours in a day + 1) or 8 (days in a week + 1)
long m_nPeriodsSet; // number of periods for which we have data filled in.
long m_iPeriod; // index. 0 <= m_iPeriod < m_nPeriodsSet. Zeroed by InitEnum,
// incremented by GetNext or SetNext.
time_t *m_ptime; // points to array of times: start time of relevant time period
// (typically beginning of a clock hour or calendar day).
long *m_pCount; // points to array totals, each the total for correspondingly
// indexed time period
};
////////////////////////////////////////////////////////////////////////////////////
// CHourlyTotals class declaration
// CHourlyTotals intended for displaying hourly totals
////////////////////////////////////////////////////////////////////////////////////
class CHourlyTotals : public CPeriodicTotals
{
public:
CHourlyTotals();
~CHourlyTotals();
virtual CString HTMLDisplay() const;
};
////////////////////////////////////////////////////////////////////////////////////
// CDailyTotals class declaration
// CDailyTotals intended for displaying dayly totals
////////////////////////////////////////////////////////////////////////////////////
class CDailyTotals : public CPeriodicTotals
{
public:
CDailyTotals();
~CDailyTotals();
virtual CString HTMLDisplay() const;
};
////////////////////////////////////////////////////////////////////////////////////
// CCounterLocation class declaration
// CCounterLocation is a mean to identify counter within the global counter pool
////////////////////////////////////////////////////////////////////////////////////
class CCounterLocation
{
public:
// prefixes for scope names
static LPCTSTR m_GlobalStr;
static LPCTSTR m_TopicStr;
static LPCTSTR m_ThreadStr;
// counter IDs
enum EId {
eIdGeneric,
// counters that are realized
eIdProgramContemporary,
eIdStatusAccess,
eIdActionAccess,
eIdTotalAccessStart,
eIdTotalAccessFinish,
eIdRequestUnknown,
eIdRequestRejected,
eIdErrorLogged,
// status information that I see as counters.
// Oleg 10-20-98
eIdWorkingThread,
eIdQueueItem,
eIdProgressItem,
// status information that I think can be emulated as counters
// Oleg 10-21-98
eIdKnownTopic,
eIdTopicNotTriedLoad,
eIdTopicFailedLoad,
// topic - bound counters
eIdTopicLoad,
eIdTopicLoadOK,
eIdTopicEvent,
eIdTopicHit,
eIdTopicHitNewCookie,
eIdTopicHitOldCookie,
};
private:
const CString m_Scope; // scope where the counter is used (i.e. "Topic start", "Thread 1" and so on)
EId m_Id; // identifier of the counter within the scope
public:
CCounterLocation(EId id, LPCTSTR scope =m_GlobalStr);
virtual ~CCounterLocation();
public:
bool operator == (const CCounterLocation& sib) {return m_Scope == sib.m_Scope && m_Id == sib.m_Id;}
public:
CString GetScope() {return m_Scope;}
EId GetId() {return m_Id;}
};
////////////////////////////////////////////////////////////////////////////////////
// CAbstractCounter class declaration
// CAbstractCounter* are saved in counter pool
////////////////////////////////////////////////////////////////////////////////////
// >>>(probably ignore for V3.0) There has been some disagreement over whether it is
// appropriate for CAbstractCounter to inherit from CCounterLocation.
// JM says (10/29/98):
// This seems to me to be the same type of thinking as when pointers to the previous and
// next item are made part of a class that someone intends to put in a doubly linked list.
// They are NOT inherent to the class. They ought instead to be part of some other class
// that manages CAbstractCounters.
// Oleg replies (11/2/98)
// Since all counters are elements of a global pool, we have somehow to identify them
// in this pool. If the way, we are identifying counters, changes (from name - id to
// name1 - name2 - id for example), we change only CCounterLocation part of counter classes.
// I see no reasons to make CCounterLocation an instance in counter class:
// 1. we definitely have only one CCounterLocation per counter
// 2. in case if inheritance we do not need additional interface for accessing CCounterLocation
// JM follows this up (11/5/98):
// There is nothing wrong with this approach as such. There is, however, an issue of design
// philosophy that at some point we should address. For the most part, we follow the style
// of STL. Classes are normally designed with no regard to the fact that they will be
// contained in a collection. Here, the counter class knows about the enumeration type
// used to identify counters. This is sort of as if the values in an STL map had to know
// about the keys mapped to those values.
// I would have designed CCounterMgr as an "object factory", providing a means to
// manufacture named counters much as Win32 manufactures named synchronization primitives
// (e.g. a named Mutex or Semaphore). To indicate that an event has occurred, you would
// increment a named counter; for status reporting, you would ask for values of that
// named counter. (In theory, the "names" might either be text or numbers. The scheme
// would have to allow for some means of manufacturing several distinct counters for
// each topic in the catalog.)
class CAbstractCounter : public CCounterLocation
{
protected: // we do not get instances of this class (evermore this is an abstract class)
CAbstractCounter(EId id =eIdGeneric, CString scope =m_GlobalStr);
virtual ~CAbstractCounter();
public:
virtual void Increment() = 0;
virtual void Clear() = 0;
virtual void Init(long count) = 0; // init counter with a number - in order to emulate
// counting process
};
////////////////////////////////////////////////////////////////////////////////////
// CCounter class declaration
// A simple counter
////////////////////////////////////////////////////////////////////////////////////
class CCounter : public CAbstractCounter
{
public:
CCounter(EId id =eIdGeneric, CString scope =m_GlobalStr);
~CCounter();
// overrides
void Increment();
void Clear();
void Init(long count);
// specific to this class
long Get() const;
private:
long m_Count;
};
////////////////////////////////////////////////////////////////////////////////////
// CHourlyCounter class declaration
// CHourlyCounter is not supposed to be instantiated by user
////////////////////////////////////////////////////////////////////////////////////
class CHourlyCounter : public CAbstractCounter
{
friend class CHourlyDailyCounter;
protected:
CHourlyCounter();
public:
~CHourlyCounter();
// overrides
void Increment();
void Clear();
void Init(long count);
// specific to this class
long GetDayCount();
void GetHourlies(CHourlyTotals & totals);
private:
void SetHour();
private:
long m_ThisHour; // hour of the day, 0-24. -1 means uninitialized.
time_t m_ThisTime; // time corresponding to START of hour.
CCounter m_arrCount[24]; // 24 "bins", one for each hour of the day.
long m_nThisHourYesterday; // maintains a whole hour count for the hour 24 hours ago.
HANDLE m_hMutex;
};
////////////////////////////////////////////////////////////////////////////////////
// CDailyCounter class declaration
// CDailyCounter is not supposed to be instantiated by user
////////////////////////////////////////////////////////////////////////////////////
class CDailyCounter : public CAbstractCounter
{
friend class CHourlyDailyCounter;
protected:
CDailyCounter();
public:
~CDailyCounter();
// overrides
void Increment();
void Clear();
void Init(long count);
// specific to this class
long GetWeekCount();
void GetDailies(CDailyTotals & totals);
private:
void SetDay();
private:
long m_ThisDay; // day of the week, 0(Sunday)-6(Saturday). -1 means uninitialized.
time_t m_ThisTime; // time corresponding to START of day.
CCounter m_arrCount[7]; // 7 "bins", one for each day of the week.
long m_nThisDayLastWeek; // maintains a whole day count for the same day last week.
HANDLE m_hMutex;
};
////////////////////////////////////////////////////////////////////////////////////
// CHourlyDailyCounter class declaration
// CHourlyDailyCounter is an ONLY class used for counting events
////////////////////////////////////////////////////////////////////////////////////
class CHourlyDailyCounter : public CAbstractCounter
{
public:
CHourlyDailyCounter(EId id =eIdGeneric, CString scope =m_GlobalStr);
~CHourlyDailyCounter();
// overrides
void Increment();
void Clear();
void Init(long count);
// specific to this class
long GetDayCount();
void GetHourlies(CHourlyTotals & totals);
long GetWeekCount();
void GetDailies(CDailyTotals & totals);
long GetTotal() const;
time_t GetTimeFirst() const;
time_t GetTimeLast() const;
time_t GetTimeCleared() const;
time_t GetTimeCreated() const;
time_t GetTimeNow() const; // time the object is being questioned
private:
CHourlyCounter m_hourly;
CDailyCounter m_daily;
long m_Total; // total since system startup or count cleared
time_t m_timeFirst; // chronologically first time count was incremented
time_t m_timeLast; // chronologically last time count was incremented
time_t m_timeCleared; // last time init'd or cleared
time_t m_timeCreated; // time the object was instantiated
HANDLE m_hMutex;
};
////////////////////////////////////////////////////////////////////////////////////
// DisplayCounter classes
////////////////////////////////////////////////////////////////////////////////////
class CAbstractDisplayCounter
{
protected:
CAbstractCounter* m_pAbstractCounter;
public:
CAbstractDisplayCounter(CAbstractCounter* counter) : m_pAbstractCounter(counter) {}
virtual ~CAbstractDisplayCounter() {}
public:
virtual CString Display() = 0;
};
class CDisplayCounterTotal : public CAbstractDisplayCounter
{
public:
CDisplayCounterTotal(CHourlyDailyCounter* counter) : CAbstractDisplayCounter(counter) {}
~CDisplayCounterTotal() {}
public:
virtual CString Display();
};
class CDisplayCounterCurrentDateTime : public CAbstractDisplayCounter
{
public:
CDisplayCounterCurrentDateTime(CHourlyDailyCounter* counter) : CAbstractDisplayCounter(counter) {}
~CDisplayCounterCurrentDateTime() {}
public:
virtual CString Display();
};
class CDisplayCounterCreateDateTime : public CAbstractDisplayCounter
{
public:
CDisplayCounterCreateDateTime(CHourlyDailyCounter* counter) : CAbstractDisplayCounter(counter) {}
~CDisplayCounterCreateDateTime() {}
public:
virtual CString Display();
};
class CDisplayCounterFirstDateTime : public CAbstractDisplayCounter
{
public:
CDisplayCounterFirstDateTime(CHourlyDailyCounter* counter) : CAbstractDisplayCounter(counter) {}
~CDisplayCounterFirstDateTime() {}
public:
virtual CString Display();
};
class CDisplayCounterLastDateTime : public CAbstractDisplayCounter
{
public:
CDisplayCounterLastDateTime(CHourlyDailyCounter* counter) : CAbstractDisplayCounter(counter) {}
~CDisplayCounterLastDateTime() {}
public:
virtual CString Display();
};
class CDisplayCounterDailyHourly : public CAbstractDisplayCounter
{
protected:
CDailyTotals* m_pDailyTotals;
CHourlyTotals* m_pHourlyTotals;
public:
CDisplayCounterDailyHourly(CHourlyDailyCounter* counter,
CDailyTotals* daily,
CHourlyTotals* hourly)
: CAbstractDisplayCounter(counter),
m_pDailyTotals(daily),
m_pHourlyTotals(hourly)
{}
~CDisplayCounterDailyHourly() {}
public:
virtual CString Display();
};
#endif // !defined(AFX_COUNTER_H__07B5ABBD_2005_11D2_95D0_00C04FC22ADD__INCLUDED_)