diff options
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/access/transam.h | 18 | ||||
-rw-r--r-- | src/include/access/xlog.h | 171 | ||||
-rw-r--r-- | src/include/access/xlogdefs.h | 41 | ||||
-rw-r--r-- | src/include/access/xlogutils.h | 10 | ||||
-rw-r--r-- | src/include/catalog/pg_control.h | 115 | ||||
-rw-r--r-- | src/include/miscadmin.h | 4 | ||||
-rw-r--r-- | src/include/storage/ipc.h | 4 | ||||
-rw-r--r-- | src/include/tcop/tcopprot.h | 3 | ||||
-rw-r--r-- | src/include/utils/pg_crc.h | 115 |
9 files changed, 406 insertions, 75 deletions
diff --git a/src/include/access/transam.h b/src/include/access/transam.h index 620f6e59105..460de699886 100644 --- a/src/include/access/transam.h +++ b/src/include/access/transam.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: transam.h,v 1.29 2001/01/24 19:43:19 momjian Exp $ + * $Id: transam.h,v 1.30 2001/03/13 01:17:06 tgl Exp $ * * NOTES * Transaction System Version 101 now support proper oid @@ -79,7 +79,7 @@ typedef unsigned char XidStatus;/* (2 bits) */ * their numbering at 512. * * The first 4 bytes of this relation store the version - * number of the transction system. + * number of the transaction system. * ---------------- */ typedef struct LogRelationContentsData @@ -100,13 +100,16 @@ typedef LogRelationContentsData *LogRelationContents; * is updated in place whenever the variables change. * * The first 4 bytes of this relation store the version - * number of the transction system. + * number of the transaction system. * * Currently, the relation has only one page and the next * available xid, the last committed xid and the next * available oid are stored there. + * + * XXX As of 7.1, pg_variable isn't used anymore; this is dead code. * ---------------- */ +#ifdef NOT_USED typedef struct VariableRelationContentsData { XLogRecPtr LSN; @@ -117,6 +120,7 @@ typedef struct VariableRelationContentsData } VariableRelationContentsData; typedef VariableRelationContentsData *VariableRelationContents; +#endif /* NOT_USED */ /* * VariableCache is placed in shmem and used by @@ -124,8 +128,9 @@ typedef VariableRelationContentsData *VariableRelationContents; */ typedef struct VariableCacheData { - TransactionId nextXid; - Oid nextOid; + TransactionId nextXid; /* next XID to assign */ + uint32 xidCount; /* XIDs available before must do XLOG work */ + Oid nextOid; /* and similarly for OIDs */ uint32 oidCount; } VariableCacheData; @@ -184,7 +189,8 @@ extern int RecoveryCheckingEnableState; extern bool AMI_OVERRIDE; /* in varsup.c */ -extern int OidGenLockId; +extern SPINLOCK OidGenLockId; +extern SPINLOCK XidGenLockId; extern VariableCache ShmemVariableCache; #endif /* TRAMSAM_H */ diff --git a/src/include/access/xlog.h b/src/include/access/xlog.h index c17bf32cc55..dd079496ed6 100644 --- a/src/include/access/xlog.h +++ b/src/include/access/xlog.h @@ -3,7 +3,10 @@ * * PostgreSQL transaction log manager * - * $Header: /cvsroot/pgsql/src/include/access/xlog.h,v 1.18 2001/02/26 00:50:07 tgl Exp $ + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $Id: xlog.h,v 1.19 2001/03/13 01:17:06 tgl Exp $ */ #ifndef XLOG_H #define XLOG_H @@ -11,97 +14,126 @@ #include "access/rmgr.h" #include "access/transam.h" #include "access/xlogdefs.h" -#include "access/xlogutils.h" +#include "utils/pg_crc.h" -typedef struct crc64 -{ - uint32 crc1; - uint32 crc2; -} crc64; +/* + * Header for each record in XLOG + * + * NOTE: xl_len counts only the rmgr data, not the XLogRecord header, + * and also not any backup blocks appended to the record (which are signaled + * by xl_info flag bits). The total space needed for an XLOG record is + * really: + * + * SizeOfXLogRecord + xl_len + n_backup_blocks * (sizeof(BkpBlock) + BLCKSZ) + */ typedef struct XLogRecord { - crc64 xl_crc; + crc64 xl_crc; /* CRC for this record */ XLogRecPtr xl_prev; /* ptr to previous record in log */ XLogRecPtr xl_xact_prev; /* ptr to previous record of this xact */ TransactionId xl_xid; /* xact id */ - uint16 xl_len; /* total len of record *data* */ - uint8 xl_info; - RmgrId xl_rmid; /* resource manager inserted this record */ + uint16 xl_len; /* total len of rmgr data */ + uint8 xl_info; /* flag bits, see below */ + RmgrId xl_rmid; /* resource manager for this record */ /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ } XLogRecord; -#define SizeOfXLogRecord DOUBLEALIGN(sizeof(XLogRecord)) -#define MAXLOGRECSZ (2 * BLCKSZ) +#define SizeOfXLogRecord MAXALIGN(sizeof(XLogRecord)) +#define MAXLOGRECSZ 65535 /* the most that'll fit in xl_len */ -#define XLogRecGetData(record) \ - ((char*)record + SizeOfXLogRecord) +#define XLogRecGetData(record) ((char*) (record) + SizeOfXLogRecord) /* - * When there is no space on current page we continue - * on the next page with subrecord. + * XLOG uses only low 4 bits of xl_info. High 4 bits may be used by rmgr. */ -typedef struct XLogSubRecord -{ - uint16 xl_len; /* len of data left */ - - /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ - -} XLogSubRecord; - -#define SizeOfXLogSubRecord DOUBLEALIGN(sizeof(XLogSubRecord)) +#define XLR_INFO_MASK 0x0F /* - * XLOG uses only low 4 bits of xl_info. - * High 4 bits may be used by rmgr... - * - * We support backup of 2 blocks per record only. - * If we backed up some of these blocks then we use - * flags below to signal rmgr about this on recovery. + * We support backup of up to 2 disk blocks per XLOG record (could support + * more if we cared to dedicate more xl_info bits for this purpose; currently + * do not need more than 2 anyway). If we backed up any disk blocks then we + * use flag bits in xl_info to signal it. */ -#define XLR_SET_BKP_BLOCK(iblk) (0x08 >> iblk) +#define XLR_BKP_BLOCK_MASK 0x0C /* all info bits used for bkp blocks */ +#define XLR_MAX_BKP_BLOCKS 2 +#define XLR_SET_BKP_BLOCK(iblk) (0x08 >> (iblk)) #define XLR_BKP_BLOCK_1 XLR_SET_BKP_BLOCK(0) /* 0x08 */ #define XLR_BKP_BLOCK_2 XLR_SET_BKP_BLOCK(1) /* 0x04 */ -#define XLR_INFO_MASK 0x0F /* * Sometimes we log records which are out of transaction control. - * Rmgr may use flag below for this purpose. + * Rmgr may "or" XLOG_NO_TRAN into info passed to XLogInsert to indicate this. */ #define XLOG_NO_TRAN XLR_INFO_MASK -#define XLOG_PAGE_MAGIC 0x17345168 +/* + * Header info for a backup block appended to an XLOG record. + * + * Note that the backup block has its own CRC, and is not covered by + * the CRC of the XLOG record proper. Also note that we don't attempt + * to align either the BkpBlock struct or the block's data. + */ +typedef struct BkpBlock +{ + crc64 crc; + RelFileNode node; + BlockNumber block; +} BkpBlock; -typedef struct XLogPageHeaderData +/* + * When there is not enough space on current page for whole record, we + * continue on the next page with continuation record. (However, the + * XLogRecord header will never be split across pages; if there's less than + * SizeOfXLogRecord space left at the end of a page, we just waste it.) + * + * Note that xl_rem_len includes backup-block data, unlike xl_len in the + * initial header. + */ +typedef struct XLogContRecord { - uint32 xlp_magic; - uint16 xlp_info; -} XLogPageHeaderData; + uint32 xl_rem_len; /* total len of remaining data for record */ -#define SizeOfXLogPHD DOUBLEALIGN(sizeof(XLogPageHeaderData)) + /* ACTUAL LOG DATA FOLLOWS AT END OF STRUCT */ -typedef XLogPageHeaderData *XLogPageHeader; +} XLogContRecord; -/* When record crosses page boundary */ -#define XLP_FIRST_IS_SUBRECORD 0x0001 +#define SizeOfXLogContRecord MAXALIGN(sizeof(XLogContRecord)) -#define XLByteLT(left, right) \ - (right.xlogid > left.xlogid || \ - (right.xlogid == left.xlogid && right.xrecoff > left.xrecoff)) +/* + * Each page of XLOG file has a header like this: + */ +#define XLOG_PAGE_MAGIC 0x17345169 /* can be used as WAL version indicator */ -#define XLByteLE(left, right) \ - (right.xlogid > left.xlogid || \ - (right.xlogid == left.xlogid && right.xrecoff >= left.xrecoff)) +typedef struct XLogPageHeaderData +{ + uint32 xlp_magic; /* magic value for correctness checks */ + uint16 xlp_info; /* flag bits, see below */ +} XLogPageHeaderData; -#define XLByteEQ(left, right) \ - (right.xlogid == left.xlogid && right.xrecoff == left.xrecoff) +#define SizeOfXLogPHD MAXALIGN(sizeof(XLogPageHeaderData)) -extern StartUpID ThisStartUpID; /* current SUI */ -extern bool InRecovery; -extern XLogRecPtr MyLastRecPtr; +typedef XLogPageHeaderData *XLogPageHeader; + +/* When record crosses page boundary, set this flag in new page's header */ +#define XLP_FIRST_IS_CONTRECORD 0x0001 + +/* + * We break each logical log file (xlogid value) into 16Mb segments. + * One possible segment at the end of each log file is wasted, to ensure + * that we don't have problems representing last-byte-position-plus-1. + */ +#define XLogSegSize ((uint32) (16*1024*1024)) +#define XLogSegsPerFile (((uint32) 0xffffffff) / XLogSegSize) +#define XLogFileSize (XLogSegsPerFile * XLogSegSize) +/* + * Method table for resource managers. + * + * RmgrTable[] is indexed by RmgrId values (see rmgr.h). + */ typedef struct RmgrData { char *rm_name; @@ -112,12 +144,19 @@ typedef struct RmgrData extern RmgrData RmgrTable[]; -/* - * List of these structs is used to pass data to XLOG. - * If buffer is valid then XLOG will check if buffer must - * be backup-ed. For backup-ed buffer data will not be - * inserted into record (and XLOG sets - * XLR_BKP_BLOCK_X bit in xl_info). +/*-------------------- + * List of these structs is used to pass data to XLogInsert(). + * + * If buffer is valid then XLOG will check if buffer must be backed up + * (ie, whether this is first change of that page since last checkpoint). + * If so, the whole page contents are attached to the XLOG record, and XLOG + * sets XLR_BKP_BLOCK_X bit in xl_info. Note that the buffer must be pinned + * and locked while this is going on, so that it won't change under us. + * NB: when this happens, we do not bother to insert the associated data into + * the XLOG record, since we assume it's present in the buffer. Therefore, + * rmgr redo routines MUST pay attention to XLR_BKP_BLOCK_X to know what + * is actually stored in the XLOG record. + *-------------------- */ typedef struct XLogRecData { @@ -127,11 +166,13 @@ typedef struct XLogRecData struct XLogRecData *next; } XLogRecData; +extern StartUpID ThisStartUpID; /* current SUI */ +extern bool InRecovery; +extern XLogRecPtr MyLastRecPtr; + extern XLogRecPtr XLogInsert(RmgrId rmid, uint8 info, XLogRecData *rdata); extern void XLogFlush(XLogRecPtr RecPtr); -extern void CreateCheckPoint(bool shutdown); - extern void xlog_redo(XLogRecPtr lsn, XLogRecord *record); extern void xlog_undo(XLogRecPtr lsn, XLogRecord *record); extern void xlog_desc(char *buf, uint8 xl_info, char* rec); @@ -145,6 +186,10 @@ extern void StartupXLOG(void); extern void ShutdownXLOG(void); extern void CreateCheckPoint(bool shutdown); extern void SetThisStartUpID(void); +extern void XLogPutNextXid(TransactionId nextXid); +extern void XLogPutNextOid(Oid nextOid); +extern void SetRedoRecPtr(void); +extern void GetRedoRecPtr(void); /* in storage/ipc/sinval.c, but don't want to declare in sinval.h because * we'd have to include xlog.h into that ... diff --git a/src/include/access/xlogdefs.h b/src/include/access/xlogdefs.h index ce1b3ef8cf6..bc7f9e1a36d 100644 --- a/src/include/access/xlogdefs.h +++ b/src/include/access/xlogdefs.h @@ -1,21 +1,56 @@ /* - * * xlogdefs.h * * Postgres transaction log manager record pointer and - * system stratup number definitions + * system startup number definitions + * + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California * + * $Id: xlogdefs.h,v 1.2 2001/03/13 01:17:06 tgl Exp $ */ #ifndef XLOG_DEFS_H #define XLOG_DEFS_H +/* + * Pointer to a location in the XLOG. These pointers are 64 bits wide, + * because we don't want them ever to overflow. + * + * NOTE: xrecoff == 0 is used to indicate an invalid pointer. This is OK + * because we use page headers in the XLOG, so no XLOG record can start + * right at the beginning of a file. + * + * NOTE: the "log file number" is somewhat misnamed, since the actual files + * making up the XLOG are much smaller than 4Gb. Each actual file is an + * XLogSegSize-byte "segment" of a logical log file having the indicated + * xlogid. The log file number and segment number together identify a + * physical XLOG file. Segment number and offset within the physical file + * are computed from xrecoff div and mod XLogSegSize. + */ typedef struct XLogRecPtr { uint32 xlogid; /* log file #, 0 based */ - uint32 xrecoff; /* offset of record in log file */ + uint32 xrecoff; /* byte offset of location in log file */ } XLogRecPtr; /* + * Macros for comparing XLogRecPtrs + * + * Beware of passing expressions with side-effects to these macros, + * since the arguments may be evaluated multiple times. + */ +#define XLByteLT(a, b) \ + ((a).xlogid < (b).xlogid || \ + ((a).xlogid == (b).xlogid && (a).xrecoff < (b).xrecoff)) + +#define XLByteLE(a, b) \ + ((a).xlogid < (b).xlogid || \ + ((a).xlogid == (b).xlogid && (a).xrecoff <= (b).xrecoff)) + +#define XLByteEQ(a, b) \ + ((a).xlogid == (b).xlogid && (a).xrecoff == (b).xrecoff) + +/* * StartUpID (SUI) - system startups counter. It's to allow removing * pg_log after shutdown, in future. */ diff --git a/src/include/access/xlogutils.h b/src/include/access/xlogutils.h index 016381f0d2b..1f1fff7c07f 100644 --- a/src/include/access/xlogutils.h +++ b/src/include/access/xlogutils.h @@ -1,3 +1,13 @@ +/* + * xlogutils.h + * + * PostgreSQL transaction log manager utility routines + * + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $Id: xlogutils.h,v 1.6 2001/03/13 01:17:06 tgl Exp $ + */ #ifndef XLOG_UTILS_H #define XLOG_UTILS_H diff --git a/src/include/catalog/pg_control.h b/src/include/catalog/pg_control.h new file mode 100644 index 00000000000..97d0e13e783 --- /dev/null +++ b/src/include/catalog/pg_control.h @@ -0,0 +1,115 @@ +/*------------------------------------------------------------------------- + * + * pg_control.h + * The system control file "pg_control" is not a heap relation. + * However, we define it here so that the format is documented. + * + * + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $Id: pg_control.h,v 1.1 2001/03/13 01:17:06 tgl Exp $ + * + *------------------------------------------------------------------------- + */ +#ifndef PG_CONTROL_H +#define PG_CONTROL_H + +#include <time.h> + +#include "access/xlogdefs.h" +#include "utils/pg_crc.h" + + +/* Version identifier for this pg_control format */ +#define PG_CONTROL_VERSION 71 + +/* + * Body of CheckPoint XLOG records. This is declared here because we keep + * a copy of the latest one in pg_control for possible disaster recovery. + */ +typedef struct CheckPoint +{ + XLogRecPtr redo; /* next RecPtr available when we */ + /* began to create CheckPoint */ + /* (i.e. REDO start point) */ + XLogRecPtr undo; /* first record of oldest in-progress */ + /* transaction when we started */ + /* (i.e. UNDO end point) */ + StartUpID ThisStartUpID; /* current SUI */ + TransactionId nextXid; /* next free XID */ + Oid nextOid; /* next free OID */ + time_t time; /* time stamp of checkpoint */ +} CheckPoint; + +/* XLOG info values for XLOG rmgr */ +#define XLOG_CHECKPOINT_SHUTDOWN 0x00 +#define XLOG_CHECKPOINT_ONLINE 0x10 +#define XLOG_NEXTXID 0x20 +#define XLOG_NEXTOID 0x30 + + +/* System status indicator */ +typedef enum DBState +{ + DB_STARTUP = 0, + DB_SHUTDOWNED, + DB_SHUTDOWNING, + DB_IN_RECOVERY, + DB_IN_PRODUCTION +} DBState; + +#define LOCALE_NAME_BUFLEN 128 + +/* + * Contents of pg_control. + * + * NOTE: try to keep this under 512 bytes so that it will fit on one physical + * sector of typical disk drives. This reduces the odds of corruption due to + * power failure midway through a write. Currently it fits comfortably, + * but we could probably reduce LOCALE_NAME_BUFLEN if things get tight. + */ + +typedef struct ControlFileData +{ + crc64 crc; /* CRC for remainder of struct */ + + /* + * Version identifier information. Keep these fields at the front, + * especially pg_control_version; they won't be real useful if they + * move around. + * + * pg_control_version identifies the format of pg_control itself. + * catalog_version_no identifies the format of the system catalogs. + * + * There are additional version identifiers in individual files; + * for example, WAL logs contain per-page magic numbers that can serve + * as version cues for the WAL log. + */ + uint32 pg_control_version; /* PG_CONTROL_VERSION */ + uint32 catalog_version_no; /* see catversion.h */ + + /* + * System status data + */ + DBState state; /* see enum above */ + time_t time; /* time stamp of last pg_control update */ + uint32 logId; /* current log file id */ + uint32 logSeg; /* current log file segment, + 1 */ + XLogRecPtr checkPoint; /* last check point record ptr */ + XLogRecPtr prevCheckPoint; /* previous check point record ptr */ + + CheckPoint checkPointCopy; /* copy of last check point record */ + + /* + * This data is used to make sure that configuration of this database + * is compatible with the backend executable. + */ + uint32 blcksz; /* block size for this DB */ + uint32 relseg_size; /* blocks per segment of large relation */ + /* active locales --- "C" if compiled without USE_LOCALE: */ + char lc_collate[LOCALE_NAME_BUFLEN]; + char lc_ctype[LOCALE_NAME_BUFLEN]; +} ControlFileData; + +#endif /* PG_CONTROL_H */ diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h index 46d7ab534ea..851174f3966 100644 --- a/src/include/miscadmin.h +++ b/src/include/miscadmin.h @@ -12,7 +12,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: miscadmin.h,v 1.81 2001/02/10 02:31:28 tgl Exp $ + * $Id: miscadmin.h,v 1.82 2001/03/13 01:17:06 tgl Exp $ * * NOTES * some of the information in this file should be moved to @@ -283,6 +283,8 @@ extern ProcessingMode Mode; extern bool CreateDataDirLockFile(const char *datadir, bool amPostmaster); extern bool CreateSocketLockFile(const char *socketfile, bool amPostmaster); extern void TouchSocketLockFile(void); +extern void RecordSharedMemoryInLockFile(IpcMemoryKey shmKey, + IpcMemoryId shmId); extern void ValidatePgVersion(const char *path); diff --git a/src/include/storage/ipc.h b/src/include/storage/ipc.h index 3173121850d..f1e1e6096cd 100644 --- a/src/include/storage/ipc.h +++ b/src/include/storage/ipc.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: ipc.h,v 1.47 2001/02/10 02:31:28 tgl Exp $ + * $Id: ipc.h,v 1.48 2001/03/13 01:17:06 tgl Exp $ * * Some files that would normally need to include only sys/ipc.h must * instead include this file because on Ultrix, sys/ipc.h is not designed @@ -105,6 +105,8 @@ extern int IpcSemaphoreGetValue(IpcSemaphoreId semId, int sem); extern PGShmemHeader *IpcMemoryCreate(uint32 size, bool makePrivate, int permission); +extern bool SharedMemoryIsInUse(IpcMemoryKey shmKey, IpcMemoryId shmId); + /* ipci.c */ extern void CreateSharedMemoryAndSemaphores(bool makePrivate, int maxBackends); diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 52d719c6c5f..94af6e71133 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $Id: tcopprot.h,v 1.38 2001/01/24 19:43:28 momjian Exp $ + * $Id: tcopprot.h,v 1.39 2001/03/13 01:17:06 tgl Exp $ * * OLD COMMENTS * This file was created so that other c files could get the two @@ -41,6 +41,7 @@ extern void pg_exec_query_string(char *query_string, #endif /* BOOTSTRAP_INCLUDE */ extern void die(SIGNAL_ARGS); +extern void quickdie(SIGNAL_ARGS); extern int PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const char *username); extern void ResetUsage(void); diff --git a/src/include/utils/pg_crc.h b/src/include/utils/pg_crc.h new file mode 100644 index 00000000000..18e012bbcd0 --- /dev/null +++ b/src/include/utils/pg_crc.h @@ -0,0 +1,115 @@ +/* + * pg_crc.h + * + * PostgreSQL 64-bit CRC support + * + * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $Id: pg_crc.h,v 1.1 2001/03/13 01:17:06 tgl Exp $ + */ +#ifndef PG_CRC_H +#define PG_CRC_H + +/* + * If we have a 64-bit integer type, then a 64-bit CRC looks just like the + * usual sort of implementation. (See Ross Williams' excellent introduction + * A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS, available from + * ftp://ftp.rocksoft.com/papers/crc_v3.txt or several other net sites.) + * If we have no working 64-bit type, then fake it with two 32-bit registers. + * + * The present implementation is a normal (not "reflected", in Williams' + * terms) 64-bit CRC, using initial all-ones register contents and a final + * bit inversion. The chosen polynomial is borrowed from the DLT1 spec + * (ECMA-182, available from http://www.ecma.ch/ecma1/STAND/ECMA-182.HTM): + * + * x^64 + x^62 + x^57 + x^55 + x^54 + x^53 + x^52 + x^47 + x^46 + x^45 + + * x^40 + x^39 + x^38 + x^37 + x^35 + x^33 + x^32 + x^31 + x^29 + x^27 + + * x^24 + x^23 + x^22 + x^21 + x^19 + x^17 + x^13 + x^12 + x^10 + x^9 + + * x^7 + x^4 + x + 1 + */ + +#ifdef INT64_IS_BUSTED + +/* + * crc0 represents the LSBs of the 64-bit value, crc1 the MSBs. Note that + * with crc0 placed first, the output of 32-bit and 64-bit implementations + * will be bit-compatible only on little-endian architectures. If it were + * important to make the two possible implementations bit-compatible on + * all machines, we could do a configure test to decide how to order the + * two fields, but it seems not worth the trouble. + */ +typedef struct crc64 +{ + uint32 crc0; + uint32 crc1; +} crc64; + +/* Initialize a CRC accumulator */ +#define INIT_CRC64(crc) ((crc).crc0 = 0xffffffff, (crc).crc1 = 0xffffffff) + +/* Finish a CRC calculation */ +#define FIN_CRC64(crc) ((crc).crc0 ^= 0xffffffff, (crc).crc1 ^= 0xffffffff) + +/* Accumulate some (more) bytes into a CRC */ +#define COMP_CRC64(crc, data, len) \ +do { \ + uint32 __crc0 = (crc).crc0; \ + uint32 __crc1 = (crc).crc1; \ + unsigned char *__data = (unsigned char *) (data); \ + uint32 __len = (len); \ +\ + while (__len-- > 0) \ + { \ + int __tab_index = ((int) (__crc1 >> 24) ^ *__data++) & 0xFF; \ + __crc1 = crc_table1[__tab_index] ^ ((__crc1 << 8) | (__crc0 >> 24)); \ + __crc0 = crc_table0[__tab_index] ^ (__crc0 << 8); \ + } \ + (crc).crc0 = __crc0; \ + (crc).crc1 = __crc1; \ +} while (0) + +/* Check for equality of two CRCs */ +#define EQ_CRC64(c1,c2) ((c1).crc0 == (c2).crc0 && (c1).crc1 == (c2).crc1) + +/* Constant table for CRC calculation */ +extern const uint32 crc_table0[]; +extern const uint32 crc_table1[]; + +#else /* int64 works */ + +typedef struct crc64 +{ + uint64 crc0; +} crc64; + +/* Initialize a CRC accumulator */ +#define INIT_CRC64(crc) ((crc).crc0 = (uint64) 0xffffffffffffffff) + +/* Finish a CRC calculation */ +#define FIN_CRC64(crc) ((crc).crc0 ^= (uint64) 0xffffffffffffffff) + +/* Accumulate some (more) bytes into a CRC */ +#define COMP_CRC64(crc, data, len) \ +do { \ + uint64 __crc0 = (crc).crc0; \ + unsigned char *__data = (unsigned char *) (data); \ + uint32 __len = (len); \ +\ + while (__len-- > 0) \ + { \ + int __tab_index = ((int) (__crc0 >> 56) ^ *__data++) & 0xFF; \ + __crc0 = crc_table[__tab_index] ^ (__crc0 << 8); \ + } \ + (crc).crc0 = __crc0; \ +} while (0) + +/* Check for equality of two CRCs */ +#define EQ_CRC64(c1,c2) ((c1).crc0 == (c2).crc0) + +/* Constant table for CRC calculation */ +extern const uint64 crc_table[]; + +#endif /* INT64_IS_BUSTED */ + +#endif /* PG_CRC_H */ |