File DBStatsImpl.mesa
Copyright © 1985 by Xerox Corporation. All rights reserved.
Last edited by:
MBrown on 1-Mar-81 11:48:15
Cattell on October 28, 1983 2:30 pm
Willie-Sue on February 15, 1985 11:13:13 am PST
Last Edited by: Wert, August 13, 1984 2:08:53 am PDT
Donahue, March 21, 1986 3:04:04 pm PST
Widom, August 26, 1985 10:52:29 am PDT
DIRECTORY
BasicTime USING[GetClockPulses, Now, PulsesToMicroseconds],
DBStats,
IO,
Rope;
DBStatsImpl: CEDAR 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: BOOLEANFALSE;
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 CARDINALLOOPHOLE[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 CARDINALLOOPHOLE[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
};
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",
ENDCASE => "Don't know" ]
};
PNameOfTimerEvent: PUBLIC PROC[event: TimerEvent] RETURNS[ROPE] = {
RETURN[SELECT event FROM
DBFile--
AlpineFileCreateTransaction => "AlpineFileCreateTransaction",
AlpineFileFinishTransaction => "AlpineFileFinishTransaction",
AlpineFileOpen => "AlpineFileOpen",
AlpineFileReadPage => "AlpineFileReadPage",
AlpineFileWritePage => "AlpineFileWritePage",
AlpineFileGetSize => "AlpineFileGetSize",
AlpineFileSetSize =>"AlpineFileSetSize",
OpenTransaction => "OpenTransaction",
CloseTransaction => "CloseTransaction",
MarkTransaction => "MarkTransaction",
AbortTransaction => "AbortTransaction",
DeclareDomain => "DeclareDomain",
LookupDomain => "LookupDomain",
DestroyDomain => "DestroyDomain",
DeclareRelation => "DeclareRelation",
LookupRelation => "LookupRelation",
DestroyRelation => "DestroyRelation",
DeclareEntity => "DeclareEntity",
LookupEntity => "LookupEntity",
DestroyEntity => "DestroyEntity",
DeclareIndex => "DeclareIndex",
DestroyIndex => "DestroyIndex",
CreateRelship => "CreateRelship",
LookupRelship => "LookupRelship",
DestroyRelship => "DestroyRelship",
LookupProperty => "LookupProperty",
SetF => "SetF",
GetF => "GetF",
SetP => "SetP",
GetP => "GetP",
EntityInfo => "EntityInfo",
RelationSubset => "RelationSubset",
NextRelship => "NextRelship",
PrevRelship => "PrevRelship",
DomainSubset => "DomainSubset",
NextEntity => "NextEntity",
PrevEntity => "PrevEntity",
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.
Changed by wert on August 13, 1984 2:07:27 am PDT
Changed the *n (BCPL new line) to \n (cedar newline) in the formatted output strings. This makes the DB.Statistics file easier to read...
Changed by Willie-Sue on February 15, 1985
made Cedar, added tioga formatting