-- File DBStatsImpl.mesa
-- Last edited by:
-- MBrown on 1-Mar-81 11:48:15
-- Cattell on October 28, 1983 2:30 pm
-- Willie-Sue on June 24, 1982 12:02 pm
DIRECTORY
BasicTime USING[GetClockPulses, Now, PulsesToMicroseconds],
DBStats,
IO,
Rope;
DBStatsImpl: PROGRAM
IMPORTS
BasicTime,
IO,
Rope
EXPORTS
DBStats
SHARES
DBStats
= BEGIN OPEN IO, DBStats;
ROPE: TYPE = Rope.ROPE;
-- Module state
nGlitches: LONG CARDINAL ← 0;
-- Counts number of poorly-matched Starting - Stopping calls.
CounterArray: PUBLIC ARRAY CounterEvent OF LONG CARDINAL;
TimerWasStarted: REF ARRAY TimerEvent OF BOOLEAN←
NEW[ARRAY TimerEvent OF BOOLEAN];
TimeWhenStarted: REF ARRAY TimerEvent OF LONG CARDINAL←
NEW[ARRAY TimerEvent OF LONG CARDINAL];
NStopTimerCalls: REF ARRAY TimerEvent OF LONG CARDINAL←
NEW[ARRAY TimerEvent OF LONG CARDINAL];
-- Only the following structures are a function of the data gathered by StopTimer.
TotalElapsedTime: REF ARRAY TimerEvent OF LONG CARDINAL←
NEW[ARRAY TimerEvent OF LONG CARDINAL];
MaxTime: REF ARRAY TimerEvent OF LONG CARDINAL←
NEW[ARRAY TimerEvent OF LONG CARDINAL];
MinTime: REF ARRAY TimerEvent OF LONG CARDINAL←
NEW[ARRAY TimerEvent OF LONG CARDINAL];
-- Procedures (see also the inlines in DBStats).
Initialized: BOOLEAN ← FALSE;
Initialize: PUBLIC PROC[] = {
-- Don't wipe out timer events in progress, please.
nGlitches ← 0;
CounterArray ← ALL[0];
IF ~Initialized THEN TimerWasStarted↑ ← ALL[FALSE];
NStopTimerCalls↑ ← ALL[0];
TotalElapsedTime↑ ← ALL[0];
MaxTime↑ ← ALL[0];
MinTime↑ ← ALL[LAST[LONG CARDINAL]];
Initialized ← TRUE;
};
StartTimer: PUBLIC PROC[event: TimerEvent] = {
-- Called by DBStats.Starting.
IF TimerWasStarted[event] THEN nGlitches ← nGlitches + 1;
TimerWasStarted[event] ← TRUE;
TimeWhenStarted[event] ← LOOPHOLE[BasicTime.GetClockPulses[]];
};
StopTimer: PUBLIC PROC[event: TimerEvent] = {
-- Called by DBStats.Stopping.
IF ~TimerWasStarted[event] THEN {
nGlitches ← nGlitches + 1;
RETURN;
};
TimerWasStarted[event] ← FALSE;
NStopTimerCalls[event] ← NStopTimerCalls[event] + 1;
-- What is done next is a function of how elaborate the stats need to be. It might
--even be a function of event. For now, do something simple.
{
elapsedTime: LONG CARDINAL ← LOOPHOLE[BasicTime.GetClockPulses[], LONG CARDINAL] - TimeWhenStarted[event];
TotalElapsedTime[event] ← TotalElapsedTime[event] + elapsedTime;
MaxTime[event] ← MAX[elapsedTime, MaxTime[event]];
MinTime[event] ← MIN[elapsedTime, MinTime[event]];
};
};
AbortTimer: PUBLIC PROC[event: TimerEvent] = {
-- Called by DBStats.Aborting. Aborts timing of this event.
TimerWasStarted[event] ← FALSE;
};
EnumerateCounters: PROC[procToApply: PROC[CounterEvent]] = {
FOR p: CounterEvent IN CounterEvent DO procToApply[p] ENDLOOP;
};
EnumerateTimers: PROC[procToApply: PROC[TimerEvent]] = {
FOR p: TimerEvent IN TimerEvent DO procToApply[p] ENDLOOP;
};
Print: PUBLIC PROC[
heading: ROPE, out: IO.STREAM, verbose: BOOLEAN] = {
PrintHighResolutionTime: PROC[time: LONG CARDINAL] RETURNS[BOOLEAN] = {
-- Returns TRUE iff time is less than 2 ms.
time ← LOOPHOLE[BasicTime.PulsesToMicroseconds[LOOPHOLE[time]],LONG CARDINAL]/100;
-- convert to 1/10 ms units
{ms: LONG CARDINAL ← time/10;
decimal: LONG CARDINAL ← time MOD 10;
out.PutF["%g.%g", card[ms], card[decimal]];
RETURN[ms <= 1]};
};
PrintCounter: PROC[e: CounterEvent] = {
IF CounterArray[e] > 0 THEN {
out.PutF[" %g: %g events*n", rope[PNameOfCounterEvent[e]], card[CounterArray[e]]] }
ELSE IF verbose THEN { out.PutF[" %g: no events*n", rope[PNameOfCounterEvent[e]]] };
};
PrintTimer: PROC[e: TimerEvent] = {
IF NStopTimerCalls[e] > 0 THEN {
timeIsSmall: BOOLEAN;
out.PutF[" %g: ", rope[PNameOfTimerEvent[e]]];
timeIsSmall ← PrintHighResolutionTime[TotalElapsedTime[e]/NStopTimerCalls[e]];
IF timeIsSmall THEN {
avgTime: CARDINAL ←
BasicTime.PulsesToMicroseconds[LOOPHOLE[TotalElapsedTime[e]/NStopTimerCalls[e]]];
out.PutF[" ms (%g us) average time for %g events.", card[avgTime], card[NStopTimerCalls[e]]];}
ELSE
out.PutF[" ms average time for %g events.", card[NStopTimerCalls[e]]];
out.PutF[" Max = "];
[] ← PrintHighResolutionTime[MaxTime[e]];
out.PutF[", Min = "];
[] ← PrintHighResolutionTime[MinTime[e]];
out.PutF[".*n"] }
ELSE IF verbose THEN { out.PutF[" %g: no events*n", rope[PNameOfTimerEvent[e]]] };
};
currentTime: LONG CARDINAL ← LOOPHOLE[BasicTime.Now[]];
IF heading = NIL OR heading.Length[] = 0 THEN heading ← "DBStats";
out.PutF[IF verbose THEN "%g (printing all events at %g)*n"
ELSE "%g (printing nonzero events at %g)*n", IO.rope[heading], IO.time[]];
EnumerateCounters[PrintCounter];
EnumerateTimers[PrintTimer];
IF nGlitches > 0 THEN out.PutF["Note: %g out of order calls to Starting or Stopping*n", card[nGlitches]];
nGlitches ← 0;
out.PutF["*n*n"];
out.Flush[]; --force stream if necessary
};
-- This stuff will soon be provided by Cedar RTTypes; watch this space...
PNameOfCounterEvent: PROC[event: CounterEvent] RETURNS[ROPE] = {
RETURN[SELECT event FROM
CacheReadOrWrite => "CacheReadOrWrite",
CacheHTLookup => "CacheHTLookup",
CacheHTConflictInLookup => "CacheHTConflictInLookup",
CacheMiss => "CacheMiss",
CacheWritePageBack => "CacheWritePageBack",
SegmentAllocPage => "SegmentAllocPage",
SegmentFreePage => "SegmentFreePage",
StorageCreateTuple => "StorageCreateTuple",
StorageCreateSystemTuple => "StorageCreateSystemTuple",
StorageDestroyTuple => "StorageDestroyTuple",
StorageReadTupleset => "StorageReadTupleset",
StorageReadField => "StorageReadField",
StorageWriteField => "StorageWriteField",
StorageInitVecPage => "StorageInitVecPage",
StorageCheckVecPage => "StorageCheckVecPage",
StorageAllocVec => "StorageAllocVec",
StorageFreeVec => "StorageFreeVec",
StorageModifyVec => "StorageModifyVec",
StorageModifyDifficultVec => "StorageModifyDifficultVec",
StorageCompactPage => "StorageCompactPage",
DBIndexInsert => "DBIndexInsert",
DBIndexDelete => "DBIndexDelete",
DBIndexOpenScan => "DBIndexOpenScan",
DBIndexNextScan => "DBIndexNextScan",
DBIndexBiggerKey => "DBIndexBiggerKey",
DBIndexEqualKey => "DBIndexEqualKey",
BTreeSearchPage => "BTreeSearchPage",
BTreeSwapInPage => "BTreeSwapInPage",
BTreeSwapOutPage => "BTreeSwapOutPage",
CreateEntity => "CreateEntity",
CreateRelship => "CreateRelship",
ReleaseRelshipSet => "ReleaseRelshipSet",
ReleaseEntitySet => "ReleaseEntitySet",
SurrogateCreateRelship => "SurrogateCreateRelship",
SurrogateDestroyRelship => "SurrogateDestroyRelship",
DomainOf => "DomainOf",
RelationOf => "RelationOf",
SystemGetF => "SystemGetF",
DictionaryGetF => "DictionaryGetF",
DictionarySetF => "DictionarySetF",
GetTupleInfo => "GetTupleInfo",
GetTupleInfoMiss => "GetTupleInfoMiss",
GetRelationInfo => "GetRelationInfo",
GetRelationInfoMiss => "GetRelationInfoMiss",
GetAttributeInfo => "GetAttributeInfo",
GetAttributeInfoMiss => "GetAttributeInfoMiss",
GetDomainInfo => "GetDomainInfo",
GetDomainInfoMiss => "GetDomainInfoMiss",
SystemGetAttributeInfo => "GetAttributeInfoMiss",
ENDCASE => "Don't know" ]
};
PNameOfTimerEvent: PUBLIC PROC[event: TimerEvent] RETURNS[ROPE] = {
RETURN[SELECT event FROM
-- DBFile--
PilotFileCreateTransaction => "PilotFileCreateTransaction",
PilotFileFinishTransaction => "PilotFileFinishTransaction",
PilotFileOpen => "PilotFileOpen",
PilotFileReadPage => "PilotFileReadPage",
PilotFileWritePage => "PilotFileWritePage",
PilotFileGetSize => "PilotFileGetSize",
PilotFileSetSize => "PilotFileSetSize",
AlpineFileCreateTransaction => "AlpineFileCreateTransaction",
AlpineFileFinishTransaction => "AlpineFileFinishTransaction",
AlpineFileOpen => "AlpineFileOpen",
AlpineFileReadPage => "AlpineFileReadPage",
AlpineFileWritePage => "AlpineFileWritePage",
AlpineFileGetSize => "AlpineFileGetSize",
AlpineFileSetSize =>"AlpineFileSetSize",
GetP => "GetP",
SetP => "SetP",
GetF => "GetF",
SetF => "SetF",
SurrogateGetF => "SurrogateGetF",
SurrogateSetF => "SurrogateSetF",
NameOf => "NameOf",
ChangeName => "ChangeName",
DeclareEntity => "DeclareEntity",
DeclareRelship => "DeclareRelship",
DestroyEntity => "DestroyEntity",
DestroyRelship => "DestroyRelship",
RelationSubset => "RelationSubset",
DomainSubset => "DomainSubset",
NextRelship => "NextRelship",
NextEntity => "NextEntity",
PrevRelship => "PrevRelship",
PrevEntity => "PrevEntity",
GetDomainRefAttributes => "GetDomainRefAttributes",
OpenToClose => "OpenToClose",
ENDCASE => "Don't know" ]
};
END.--DBStatsImpl
CHANGE LOG
Created by MBrown on February 26, 1981 10:21 AM
-- Pilot version created by editing PerfStatsImpl.
Changed by MBrown on 1-Mar-81 11:47:23
-- Left out a few necessary things, like PNameOfTimerEvent, etc.
Changed by Cattell on 15-Dec-81 10:23:31
-- Converted to IOStream.
Changed by Cattell on April 29, 1982 10:03 pm
-- Added DBView items.
Changed by Willie-Sue on June 24, 1982 12:02 pm
-- IOStream => IO
Changed by Cattell on October 11, 1982 4:22 pm
-- Added some timer events.