220 lines
6.8 KiB
C
220 lines
6.8 KiB
C
/* node status returned from VERAccess*
|
|
/**/
|
|
typedef enum
|
|
{
|
|
nsVersion,
|
|
nsVerInDB,
|
|
nsDatabase,
|
|
nsInvalid
|
|
} NS;
|
|
|
|
/* version status returned from VERCheck
|
|
/**/
|
|
typedef enum
|
|
{
|
|
vsCommitted,
|
|
vsUncommittedByCaller,
|
|
vsUncommittedByOther
|
|
} VS;
|
|
|
|
// ===========================================================================
|
|
// RCE (Revision Control Entry)
|
|
|
|
/* operation type
|
|
/**/
|
|
typedef UINT OPER;
|
|
|
|
#define operReplace 0
|
|
#define operInsert 1
|
|
#define operFlagDelete 2
|
|
#define operNull 3 // to void an RCE
|
|
|
|
#define operExpungeLink 4
|
|
#define operExpungeBackLink 5
|
|
#define operWriteLock 6
|
|
#define operAllocExt 7
|
|
#define operDeferFreeExt 8
|
|
#define operDelete 9 // a real delete
|
|
|
|
#define operReplaceWithDeferredBI 10 // recovery only, replace deferred before image.
|
|
|
|
#define operDelta 0x0010
|
|
|
|
#define operMaskItem 0x0020
|
|
#define operInsertItem 0x0020
|
|
#define operFlagInsertItem 0x0060
|
|
#define operFlagDeleteItem 0x00a0
|
|
|
|
#define operMaskDDL 0x0100
|
|
#define operCreateTable 0x0100
|
|
#define operDeleteTable 0x0300
|
|
#define operRenameTable 0x0500
|
|
#define operAddColumn 0x0700
|
|
#define operDeleteColumn 0x0900
|
|
#define operRenameColumn 0x0b00
|
|
#define operCreateIndex 0x0d00
|
|
#define operDeleteIndex 0x0f00
|
|
#define operRenameIndex 0x1100
|
|
|
|
/* create table: table pgnoFDP
|
|
/* rename table: before image table name
|
|
/* add column: before image pfdb, NULL if not first DDL at level
|
|
/* delete column: before image pfdb, NULL if not first DDL at level
|
|
/* rename column: before image column name
|
|
/* create index: index pgnoFDP
|
|
/* delete index: index pfcb
|
|
/* rename index: before image index name
|
|
/**/
|
|
|
|
#define FOperDDL( oper ) ( (oper) & operMaskDDL )
|
|
#define FOperItem( oper ) ( (oper) & operMaskItem )
|
|
|
|
typedef struct _rce
|
|
{
|
|
struct _rce *prceHashOverflow; // hash over flow RCE chain
|
|
struct _rce *prcePrevOfNode; // previous versions for same node, lower trx
|
|
struct _rce *prcePrevOfSession; // previous RCE of same session
|
|
struct _rce *prceNextOfSession; // next RCE of same session
|
|
|
|
USHORT ibPrev; // index to prev RCE in bucket
|
|
// UNDONE: DBID->BYTE and put with level
|
|
LEVEL level; // current level of RCE, can change
|
|
BYTE bReserved; // make it aligned.
|
|
|
|
SRID bm; // bookmark of node
|
|
TRX trxPrev; // time when previous RCE is committed
|
|
TRX trxCommitted; // time when this RCE is committed
|
|
FUCB *pfucb; // for undo
|
|
|
|
// UNDONE: OPER should be UINT16 and put with cbData
|
|
OPER oper; // operation that causes creation of RCE
|
|
|
|
DBID dbid; // database id of node
|
|
WORD cbData; // length of data portion of node
|
|
|
|
// UNDONE: remove pfcb after unified bucket chain allows
|
|
// presynchronized version clean up.
|
|
FCB *pfcb; // for clean up
|
|
// UNDONE: remove bmTarget and ulDBTime after VR bookmark implementation.
|
|
// These fields should not be necessary, since version store
|
|
// will be aware of node movements.
|
|
SRID bmTarget; // for recovery of undo
|
|
QWORD qwDBTime; // for recovery of undo
|
|
|
|
struct _bf *pbfDeferredBI; // which page deferred before image is on.
|
|
struct _rce *prceDeferredBINext; // link list for deferred before image.
|
|
|
|
#ifdef DEBUG
|
|
QWORD qwDBTimeDeferredBIRemoved;
|
|
#endif
|
|
|
|
BYTE rgbData[0]; // storing the data portion of a node
|
|
} RCE;
|
|
|
|
/* first 2 SHORTs of rgbData are used to remember cbMax and cbAdjust for
|
|
* each replace operation.
|
|
*/
|
|
#define cbReplaceRCEOverhead (2 * sizeof(SHORT))
|
|
|
|
|
|
//============================================================================
|
|
// bucket
|
|
|
|
#define cbBucketHeader \
|
|
( 2 * sizeof(struct _bucket *) + sizeof(UINT) )
|
|
|
|
#define cbBucket 16384 // number of bytes in a bucket
|
|
|
|
typedef struct _bucket
|
|
{
|
|
struct _bucket *pbucketPrev; // prev bucket for same user
|
|
struct _bucket *pbucketNext; // next bucket for same user
|
|
UINT ibNewestRCE; // newest RCE within bucket
|
|
BYTE rgb[ cbBucket - cbBucketHeader ];
|
|
// space for storing RCEs
|
|
} BUCKET;
|
|
|
|
/* free extent parameter block
|
|
/**/
|
|
typedef struct {
|
|
PGNO pgnoFDP;
|
|
PGNO pgnoChildFDP;
|
|
PGNO pgnoFirst;
|
|
CPG cpgSize;
|
|
} VEREXT;
|
|
|
|
/* rename rollback parameter block
|
|
/**/
|
|
typedef struct {
|
|
CHAR szName[ JET_cbNameMost + 1 ];
|
|
CHAR szNameNew[ JET_cbNameMost + 1 ];
|
|
} VERRENAME;
|
|
|
|
|
|
/* delete column rollback parameter block
|
|
/**/
|
|
typedef struct tagVERCOLUMN
|
|
{
|
|
JET_COLTYP coltyp; // column type
|
|
FID fid; // field id
|
|
} VERCOLUMN;
|
|
|
|
|
|
/* ErrRCEClean flags
|
|
/**/
|
|
#define fRCECleanSession (1<<0)
|
|
|
|
ERR ErrVERInit( VOID );
|
|
VOID VERTerm( BOOL fNormal );
|
|
VS VsVERCheck( FUCB *pfucb, SRID bm );
|
|
NS NsVERAccessNode( FUCB *pfucb, SRID bm );
|
|
NS NsVERAccessItem( FUCB *pfucb, SRID bm );
|
|
ERR FVERUncommittedVersion( FUCB *pfucb, SRID bm );
|
|
ERR FVERDelta( FUCB *pfucb, SRID bm );
|
|
ERR ErrVERCreate( FUCB *pfucb, SRID bm, OPER oper, RCE **pprce );
|
|
ERR ErrVERModify( FUCB *pfucb, SRID bm, OPER oper, RCE **pprce);
|
|
BOOL FVERNoVersion( DBID dbid, SRID bm );
|
|
ERR ErrRCEClean( PIB *ppib, INT fCleanSession );
|
|
ERR ErrVERBeginTransaction( PIB *ppib );
|
|
VOID VERPrecommitTransaction( PIB *ppib );
|
|
VOID VERCommitTransaction( PIB *ppib, BOOL fCleanSession );
|
|
ERR ErrVERRollback(PIB *ppib);
|
|
RCE *PrceRCEGet( DBID dbid, SRID bm );
|
|
#define fDoNotUpdatePage fFalse
|
|
#define fDoUpdatePage fTrue
|
|
VOID VERSetCbAdjust(FUCB *pfucb, RCE *prce, INT cbDataNew, INT cbData, BOOL fNotUpdatePage );
|
|
INT CbVERGetNodeMax( DBID dbid, SRID bm );
|
|
INT CbVERGetNodeReserve( PIB *ppib, DBID dbid, SRID bm, INT cbCurrentData );
|
|
INT CbVERUncommittedFreed( BF *pbf );
|
|
BOOL FVERCheckUncommittedFreedSpace( BF *pbf, INT cbReq );
|
|
BOOL FVERItemVersion( DBID dbid, SRID bm, ITEM item );
|
|
BOOL FVERMostRecent( FUCB *pfucb, SRID bm );
|
|
VOID VERDeleteFromDeferredBIChain( RCE *prce );
|
|
|
|
#define ErrVERReplace( pfucb, srid, pprce ) ErrVERModify( pfucb, srid, operReplace, pprce )
|
|
#define ErrVERInsert( pfucb, srid ) ErrVERCreate( pfucb, srid, operInsert, pNil )
|
|
#define ErrVERFlagDelete( pfucb, srid ) ErrVERModify( pfucb, srid, operFlagDelete, pNil )
|
|
#define ErrVERInsertItem( pfucb, srid ) ErrVERCreate( pfucb, srid, operInsertItem, pNil )
|
|
#define ErrVERFlagInsertItem( pfucb, srid ) ErrVERModify( pfucb, srid, operFlagInsertItem, pNil )
|
|
#define ErrVERFlagDeleteItem( pfucb, srid ) ErrVERModify( pfucb, srid, operFlagDeleteItem, pNil )
|
|
#define ErrVERDelta( pfucb, srid ) ErrVERModify( pfucb, srid, operDelta, pNil )
|
|
|
|
#define ErrRCECleanAllPIB( ) ErrRCEClean( ppibNil, 0 )
|
|
|
|
#define FVERPotThere( vs, fDelete ) \
|
|
( ( (vs) != vsUncommittedByOther && !(fDelete) ) || \
|
|
(vs) == vsUncommittedByOther )
|
|
|
|
ERR ErrVERFlag( FUCB *pfucb, OPER oper, VOID *pv, INT cb );
|
|
VOID VERDeleteRce( RCE *prce );
|
|
|
|
#define FVERUndoLoggedOper( prce ) \
|
|
( prce->oper == operReplace || \
|
|
prce->oper == operInsert || \
|
|
prce->oper == operFlagDelete || \
|
|
prce->oper == operInsertItem || \
|
|
prce->oper == operFlagInsertItem || \
|
|
prce->oper == operFlagDeleteItem || \
|
|
prce->oper == operDelta )
|
|
ERR ErrVERUndo( RCE *prce );
|