406 lines
12 KiB
C++
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__
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|