2025-04-27 07:49:33 -04:00

406 lines
12 KiB
C++

/*
* @doc
*
* @module LOGSTATE.H |
* CLogState is the class that contains the current state of the log.
* It is initialized from the last restart area written to the log.
* It is updated when log records are written. The methods of this
* class determine the way a log record is laid down in the log.
* It provides the log storage with a write or read map to be used to
* write or read log records.
*
* CWriteMap defines the mapping of a log record given its length and
* starting position on the log to the log storage pages. The map
* is then used to get the memory buffers from the log storage and to
* copy the user data into the log buffers.
*
* CReadMap defines a mapping of a log record given its length and
* starting position on the log to the log storage pages where that
* record is written.
*
* @rev 0 | 16-Jan-95 | robertba | Created from Vincentf OFS code
* @rev 1 | 29-Mar-95 | wilfr | Removed transaction stuff
* @rev 2 | 03-Apr-95 | wilfr | seqno to gennum changes
*
*/
#ifndef __LOGSTATE_H__
#define __LOGSTATE_H__
class CLogMgr; //forward class declaration
/*
* @class CWriteMap |
* Provides a mapping between user supplied write records and the log storage.
*
* hungarian crm
*/
class CWriteMap
{
//@access Public Members
public:
//@cmember Constructor
CWriteMap(IN CLogStorage *pclgsto,IN ULONG ulEntryCount,IN LOGREC *algr,IN WRITELISTELEMENT *pwle);
//@cmember Default Constructor
CWriteMap();
//@cmember Destructor
~CWriteMap();
//@cmember Init after default constructor
VOID Init(IN CLogStorage *pclgsto,IN ULONG ulEntryCount,IN LOGREC *algr,IN WRITELISTELEMENT *pwle);
//@cmember Returns the computed client data plus header length.
ULONG GetRecordLength();
//@cmember sets the next range record in the write map.
VOID AddRange(IN RANGEENTRY &re);
//@cmember copy of the client data into the log storage buffers.
VOID CopyRecord(IN LOGRECHEADER &lrh);
//@cmember Sets the number of bytes that need to be allocated to align
// the next record on a ulALIGN boundary.
VOID SetAlign(IN ULONG ulAlign);
//@cmember Compute alignment bytes
ULONG GetAlign();
//@access Private Members
private:
//
// Initial Parameters
//
//@cmember Number of buffers in array 0 => linked list.
ULONG _ulEntryCount;
//@cmember Array of user buffers.
LOGREC *_algr;
//@cmember Linked list of buffers.
WRITELISTELEMENT *_pwle;
//@cmember Number of date bytes in the message.
ULONG _ulByteLength;
//@cmember Log storage reference.
CLogStorage *_pclgstr;
//@cmember Cursor variables into client buffers during copy
ULONG _ulCurrentIndex;
//@cmember The current write element
WRITELISTELEMENT *_pwleCurrentElement;
//@cmember The current length
ULONG _ulCurrentLength;
//@cmember The current address
CHAR *_pchCurrentAddress;
//@cmember Alignment bytes needed.
ULONG _ulAlign;
//@cmember Number of bytes allocated for alignment by CLogState::AttemptWrite
ULONG _ulAlignAlloc;
//
// Buffer structures for the client log record.
//
//@cmember Number of ranges where buffers must be allocated.
ULONG _ulRangeCount;
//@cmember The ranges.
RANGEENTRY _arre[4];
//
// Internal Support Routines.
//
//@cmember Returns the address and length of the next buffer to be copied.
BOOL _GetNextClientBuffer();
//@cmember Copy the client record or part of it into the buffer.
VOID _CopyBuffer(IN ULONG ulRangeIndex);
};
/*
* @class CReadMap |
* Provides a mapping between log storage records and user buffers log storage.
*
* hungarian crm
*
*/
class CReadMap
{
friend class CILogRead;
//@access Public Members
public:
//@cmember Constructor
CReadMap(IN CLogStorage *pclgs,IN ULONG ulPageSize);
//@cmember Destructor
~CReadMap();
//@cmember Initialize the read map
VOID InitReadMap(IN ULONG ulGeneration, IN ULONG ulOffset);
//@cmember Returns start & size of the record to be read
VOID GetBounds(OUT ULONG *pulOffset,OUT ULONG *pulLength);
//@cmember Get the number of buffers
ULONG GetBufCount();
//@cmember Adds a range of buffer to the map.
VOID AddRange(IN RANGEENTRY &re);
//@cmember Reads the next record and returns the buffer.
BOOL ReadRecord(
IN ULONG ulGeneration,
IN ULONG ulBufCount,
OUT ULONG *pulBufUsed,
OUT LOGRECHEADER **pplrh,
OUT LOGREC *algr,
IN BOOL fFree,
IN OUT ULONG *pulGenNum);
//@cmember Release the buffers and get the header for the next record
BOOL ReleaseAndSet(
IN ULONG ulGeneration,
IN ULONG ulNextOffset);
//@access Private Members
private:
//
// Private member functions
//
//@cmember For each page in the buffer the operation sets the address and
// length of the write array element.
VOID _SetRangeBuffers(LOGREC **pplgrNext,RANGEENTRY *preNext,ULONG *pulBufUsed,BOOL fFree);
//@cmember obtain the log storage page that contains the log header of the
// next record to be read.
VOID _SetUpResidue(IN ULONG ulGeneration);
//@cmember Get the next page
RECORDPAGE* _GetNextPage(RANGEENTRY *pre);
//
// Next record parameters.
//
//@cmember Offset of next record to be read.
ULONG _ulOffset;
//@cmember Length of next record to be read.
ULONG _ulLength;
//
// Range structures.
//
//@cmember The count of ranges
ULONG _ulRangeCount;
//@cmember The residue
RANGEENTRY _reResidue;
//@cmember Is this a residue
BOOL _fIsResidue;
//@cmember The ranges
RANGEENTRY _arre[4];
//@cmember The current log storage
CLogStorage *_pclgs;
//@cmember The current page size
ULONG _ulPageSize;
};
/*
* @class CLogState |
* Maintains the current state of the file. Is used to determine
* how log records can be written and provides the information to
* construct restart area buffers.
*
* hungarian clgs
*
*/
class CLogState // clgs
{
friend class CLogMgr;
friend class CILogStorage;
friend class CILogWrite;
friend DWORD _FlushThread(LPDWORD lpdwParam);
//@access Public Members
public:
//@cmember Constructor
CLogState(IN RESTARTLOG &rslCurrentRestartArea,IN ULONG ulSysPageSize);
//@cmember Returns a number that signifies the fraction of the log storage that is unused.
ULONG WhatFractionFree();
//@cmember Sees if a caller's log record can be fit into the
// log storage. If possible, returns the physical
// layout of the record.
ULONG AttemptWrite(IN OUT LOGRECHEADER *plrh,IN CWriteMap &cwm,IN BOOL fFlush,IN BOOL fMarkAsOldest,IN ULONG ulBytesNeeded,IN ULONG ulChkptLen,IN OUT LRP *plrpWritten,OUT ULONG *pulStartGenNum);
//@cmember Sets up a restart area buffer.
VOID GetRestartArea(OUT RESTARTLOG *prsl,OUT ULONG *pulAvailableSpace,IN BOOL fIsInit);
//@cmember Determines if a given offset and sequence number are within the current range
BOOL IsRecordInRange(IN ULONG ulGenNum,IN ULONG ulOffset,IN BOOL fChkBackEdge);
//@cmember Sets up the physical record layout for a record whose bounds are specified.
VOID AttemptRead(IN CReadMap &crm, IN BOOL fRecovery);
//@cmember Sets the oldest dirty seq no and offset in the restart area.
VOID SetOldestDirtyRecord(ULONG ulGenNum, ULONG ulOffset,RECORDPAGE *prcpg);
//@cmember Sets the position for the next record to be written and the position
// of the last record completely written. This is only called during recovery.
VOID SetLeadingEdge(ULONG ulGenNum,ULONG ulOffset,ULONG ulNextOffset,ULONG *pulLastPageOffset,ULONG *pulLastRecOffset,ULONG *pulLastPageSpace);
//@cmember Evaluates whether a checkpoint is necessary
BOOL IsCheckpointUnnecessary();
//@cmember The log storage was flushed up to the range specified
BOOL AttemptFlush(IN ULONG ulGenNum,IN ULONG ulOffset,OUT ULONG *pulFlushOffset);
//@cmember Evaluates whether a checkpoint is necessary.
VOID EnsureCheckpointSpace(IN ULONG ulBytesNeeded,IN ULONG ulTabRecLen,IN BOOL fIsLogFull);
//@access Private Members
private:
//@cmember Used to allocate a part of a log storage record page.
BOOL _MapOnePage(CReadMap &crm,RANGEENTRY *pre,ULONG *pulLength);
//@cmember Using the state in the range parameter map as many pages
// as possible for the record to be read.
BOOL _MapPageRange(CReadMap &crm,RANGEENTRY *pre,ULONG *pulLength);
//@cmember Used to allocate a part of a log storage record page.
BOOL _AllocateFromCurrent(CWriteMap &cwm,ULONG *pulLength,RANGEENTRY *pre,BOOL fFlush);
//@cmember Allocate as many pages as possible from the forward range.
BOOL _AllocatePages(CWriteMap &cwm,ULONG *pulLength,RANGEENTRY *pre);
//@cmember Handles the wrap around of a fixed size log during a write.
VOID _DoWrapAround();
//@cmember Adjusts the range variables if the allocation or map wrap around
VOID _WrapRange(RANGEENTRY *pre);
//@cmember Determines if the offset being freed is in the current range
// being used by log records. If it is the forward and backward
VOID _FreeSpace(IN ULONG ulOffset);
//@cmember Computes the state variables of the log.
VOID _ComputeState(IN BOOL fInitCall);
//@cmember Set the restart information for the oldest xaction
VOID _ComputeNextRecord(ULONG *pulGenNum,ULONG *pulOffset);
//
// Computed constants;
//
//@cmember Offset where first record page starts.
ULONG _ulFirstRecordPage;
//@cmember Number of record pages in the log.
ULONG _ulPageCount;
//
// Current storage State
//
//@cmember Position where previous write occurred.
ULONG _ulPreviousOffset;
//@cmember There are two free areas; one in front of the buffer for log
// records and the other behind it.
BOOL _fFreeWrapped;
//@cmember Size of the largest record in the log.
ULONG _ulAvailableSpace;
//@cmember Signals that records were not written between checkpoints.
BOOL _fNoRecordWritten;
//@cmember The restart area needed.
RESTARTLOG _rsl;
//
// Current Page State
//
//@cmember Offset of first byte of the current page in log storage.
ULONG _ulCurrentPageOffset;
//@cmember Offset in current page for next record. Relative to the start
// of the data area in the page.
ULONG _ulCurrentRecOffset;
//@cmember Space available in the current page.
ULONG _ulCurrentPageSpace;
//
// Forward Range State
//
//@cmember Offset of first byte of forward range in log storage.
ULONG _ulForwardOffset;
//@cmember Number of pages after current page to end of storage.
ULONG _ulForwardPageCount;
//
// Backward Range State
//
//@cmember Number of pages before first page of trailing edge.
ULONG _ulBackwardPageCount;
//
// State to support log full.
//
//@cmember Allowance for the fact that records may cause wastage up to
// sizeof(LOGRECHEADER) on a page
ULONG _ulRecOverflow;
//@cmember Set to true when the log storage cannot
// accomodate any more update records. Reset when the checkpoint after this
// condition happens.
BOOL _fLogFull;
//@cmember State to remember last oldest dirty lrp passed in.
ULONG _ulLastOldestGenNum;
//@cmember State to remember last oldest dirty lrp passed in.
ULONG _ulLastOldestOffset;
CLogMgr *m_pCLogMgr;
};
#endif // __LOGSTATE_H__