⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bops.cpp

📁 CBASE v1.01 采用Borland公司TC++编写的数据库管理源程序库
💻 CPP
字号:
/*	Copyright (c) 1989 Citadel	*/
/*	   All Rights Reserved    	*/

/* #ident	"@(#)bops.c	1.4 - 90/06/20" */

/* ansi headers */
#include <errno.h>
/*#include <stddef.h>*/
/*#include <stdlib.h>*/
/*#include <string.h>*/

/* non-ansi headers */
#include "bool.h"

/* local headers */
#include "blkio_.h"

/*man---------------------------------------------------------------------------
NAME
     b_alloc - allocate memory for block file

SYNOPSIS
     #include "blkio_.h"

     int b_alloc(bp)
     BLKFILE *bp;

DESCRIPTION
     The b_alloc function allocates the memory needed by bp.  The
     memory is initialized to all zeros.  A call to b_alloc should
     normally be followed by a call to b_initlist to construct the
     linked list for LRU replacement.

     b_alloc will fail if one or more of the following is true:

     [EINVAL]       bp is not a valid BLKFILE pointer.
     [ENOMEM]       Enough memory is not available for
                    allocation by the calling process.
     [BENOPEN]      bp is not open.

SEE ALSO
     b_free, b_initlist.

DIAGNOSTICS
     Upon successful completion, a value of 0 is returned.  Otherwise,
     a value of -1 is returned, and errno set to indicate the error.

------------------------------------------------------------------------------*/
int b_alloc(BLKFILE *bp)
{
#ifdef DEBUG
	/* validate arguments */
	if (!b_valid(bp)) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}

	/* check if not open */
	if (!(bp->flags & BIOOPEN)) {
		BEPRINT;
		errno = BENOPEN;
		return -1;
	}

	/* check for memory leak */
	if (bp->blockp != NULL || bp->blkbuf != NULL && !(bp->flags & BIOUSRBUF)) {
		BEPRINT;
		errno = BEPANIC;
		return -1;
	}
#endif
	/* check if not buffered */
	if (bp->bufcnt == 0) {
		errno = 0;
		return 0;
	}

	/* allocate buffer storage (one extra block structure for header) */
	bp->blockp = (block_t *)calloc(bp->bufcnt + 1, sizeof(block_t));
	if (bp->blockp == NULL) {
		BEPRINT;
		errno = ENOMEM;
		return -1;
	}
	if (!(bp->flags & BIOUSRBUF)) {
		bp->blkbuf = calloc((size_t)1, bp->hdrsize + bp->bufcnt * bp->blksize);
		if (bp->blkbuf == NULL) {
			BEPRINT;
			free(bp->blockp);
			bp->blockp = NULL;
			errno = ENOMEM;
			return -1;
		}
	}

	errno = 0;
	return 0;
}

/*man---------------------------------------------------------------------------
NAME
     b_blockp - pointer to block structure

SYNOPSIS
     #include "blkio_.h"

     block_t *b_blockp(bp, i)
     BLKFILE *bp;
     size_t i;

DESCRIPTION
     b_blockp returns a pointer to the ith block structure in the
     buffer list of block file bp.  If bp is not a valid open block
     file or i is not in the range [0..bp->bufcnt] the results are
     undefined.  b_blockp is a macro.

------------------------------------------------------------------------------*/
/* b_blockp is defined in blkio_.h */

/*man---------------------------------------------------------------------------
NAME
     b_blkbuf - pointer to block buffer

SYNOPSIS
     #include "blkio_.h"

     void *b_blkbuf(bp, i)
     BLKFILE *bp;
     size_t i;

DESCRIPTION
     b_blkbuf returns a pointer to the ith buffer in the buffer list
     of block file bp.  A value of zero for i indicates the header
     buffer.  If bp is not a valid BLKFILE pointer to an open file or
     i is not in the range [0..bp->bufcnt] the results are undefined.
     b_blkbuf is a macro.

------------------------------------------------------------------------------*/
/* b_blkbuf is defined in blkio_.h */

/*man---------------------------------------------------------------------------
NAME
     b_free - free memory allocated for block file

SYNOPSIS
     #include "blkio_.h"

     void b_free(bp)
     BLKFILE *bp;

DESCRIPTION
     The b_free function frees all memory allocated for block file bp.
     If bp has a user-supplied buffer storage area, it is disconnected
     from bp but is not freed.  On return from b_free, bp->blockp and
     bp->blkbuf will be NULL.

SEE ALSO
     b_alloc.

------------------------------------------------------------------------------*/
void b_free(BLKFILE *bp)
{
#ifdef DEBUG
	/* validate arguments */
	if (!b_valid(bp)) {
		BEPRINT;
		return;
	}
#endif
	/* free memory */
	if (!(bp->flags & BIOUSRBUF)) {		/* if not user-supplied buf */
		if (bp->blkbuf != NULL) {		/* free buffer */
			free(bp->blkbuf);
		}
	}
	bp->blkbuf = NULL;			/* disconnect buffer */
	if (bp->blockp != NULL) {
		free(bp->blockp);
		bp->blockp = NULL;
	}

	return;
}

/*man---------------------------------------------------------------------------
NAME
     b_get - get block from block file

SYNOPSIS
     #include "blkio_.h"

     int b_get(bp, i)
     BLKFILE *bp;
     size_t i;

DESCRIPTION
     The b_get function reads a block from block file bp into the ith
     buffer for that block file.  b_get reads the block identified by
     the block number field of the block structure associated with
     buffer i (i.e., b_blockp(bp, i)->bn); the zeroth buffer is
     always used for the header.  The read flag is set and all others
     cleared for buffer i.

     b_get will fail if one or more of the following is true:

     [EINVAL]       bp is not a valid BLKFILE pointer.
     [EINVAL]       i is not in the range [0..bp->bufcnt].
     [BEEOF]        End of file occured before end of block.
     [BENBUF]       bp is not buffered.

SEE ALSO
     b_put.

DIAGNOSTICS
     Upon successful completion, a value of 0 is returned.  Otherwise,
     a value of -1 is returned, and errno set to indicate the error.

------------------------------------------------------------------------------*/
int b_get(BLKFILE *bp, size_t i)
{
#ifdef DEBUG
	/* validate arguments */
	if (!b_valid(bp)) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}

	/* check if not open */
	if (!(bp->flags & BIOOPEN)) {
		BEPRINT;
		errno = BENOPEN;
		return -1;
	}

	/* check if file is not buffered */
	if (bp->bufcnt == 0) {
		BEPRINT;
		errno = BENBUF;
		return -1;
	}

	/* validate arguments */
	if (i > bp->bufcnt) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}

	/* check if block number set */
	if ((b_blockp(bp, i)->bn == 0) && (i != 0)) {
		BEPRINT;
		errno = BEPANIC;
		return -1;
	}

	/* check if block needs to be written to disk */
	if (b_blockp(bp, i)->flags & BLKWRITE) {
		BEPRINT;
		errno = BEPANIC;
		return -1;
	}
#endif
	/* read block from file */
	if (i == 0) {
		if (b_ugetf(bp, (bpos_t)0, (size_t)0, b_blkbuf(bp, (size_t)0), bp->hdrsize) == -1) {
			BEPRINT;
			return -1;
		}
	} else {
		if (b_ugetf(bp, b_blockp(bp, i)->bn, (size_t)0, b_blkbuf(bp, i), bp->blksize) == -1) {
			BEPRINT;
			return -1;
		}
	}

	/* set read flag and clear all others */
	b_blockp(bp, i)->flags = BLKREAD;

	errno = 0;
	return 0;
}

/*man---------------------------------------------------------------------------
NAME
     b_initlist - build linked list

SYNOPSIS
     #include "blkio_.h"

     int b_initlist(bp)
     BLKFILE *bp;

DESCRIPTION
     The b_initlist function builds the linked list of buffers for
     block file bp.  The buffer contents are deleted in the process.
     A call to b_initlist should normally follow a call to b_alloc.

     b_initlist will fail if one or more of the following is true:

     [EINVAL]       bp is not a valid block file.

SEE ALSO
     b_alloc.

DIAGNOSTICS
     Upon successful completion, a value of 0 is returned.  Otherwise,
     a value of -1 is returned, and errno set to indicate the error.

------------------------------------------------------------------------------*/
int b_initlist(BLKFILE *bp)
{
	size_t i = 0;

#ifdef DEBUG
	/* validate arguments */
	if (!b_valid(bp)) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}

	/* check if not open */
	if (!(bp->flags & BIOOPEN)) {
		BEPRINT;
		errno = BENOPEN;
		return -1;
	}
#endif
	/* initialize head and tail of list */
	bp->most = 0;
	bp->least = 0;

	/* check if not buffered */
	if (bp->bufcnt == 0) {
		errno = 0;
		return 0;
	}

	/* initialize linked list */
	bp->most = bp->bufcnt;
	bp->least = 1;
	for (i = 1; i <= bp->bufcnt; ++i) {
		b_blockp(bp, i)->bn = 0;
		b_blockp(bp, i)->flags = 0;
		b_blockp(bp, i)->more = i + 1;
		b_blockp(bp, i)->less = i - 1;
	}
	b_blockp(bp, bp->most)->more = 0;
	b_blockp(bp, bp->least)->less = 0;

	/* initialize block structure for header */
	b_blockp(bp, (size_t)0)->bn = 0;
	b_blockp(bp, (size_t)0)->flags = 0;
	b_blockp(bp, (size_t)0)->more = 0;
	b_blockp(bp, (size_t)0)->less = 0;

	/* scrub buffer storage area */
	memset(bp->blkbuf, 0, bp->hdrsize + bp->bufcnt * bp->blksize);

	errno = 0;
	return 0;
}

/*man---------------------------------------------------------------------------
NAME
     b_mkmru - make most recently used block

SYNOPSIS
     #include "blkio_.h"

     int b_mkmru(bp, i)
     BLKFILE *bp;
     size_t i;

DESCRIPTION
     The b_mkmru function moves the ith block in the buffer list to
     the most recently used end of the buffer list.

     b_mkmru will fail if one or more of the following is true:

     [EINVAL]       bp is not a valid block file.
     [EINVAL]       i is not in the range [1..bp->bufcnt].
     [BENBUF]       bp is not buffered.

DIAGNOSTICS
     Upon successful completion, a value of 0 is returned.  Otherwise,
     a value of -1 is returned, and errno set to indicate the error.

------------------------------------------------------------------------------*/
int b_mkmru(BLKFILE *bp, size_t i)
{
	size_t more = 0;
	size_t less = 0;

#ifdef DEBUG
	/* validate arguments */
	if (!b_valid(bp)) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}

	/* check if not open */
	if (!(bp->flags & BIOOPEN)) {
		BEPRINT;
		errno = BENOPEN;
		return -1;
	}

	/* check if file is not buffered */
	if (bp->bufcnt == 0) {
		BEPRINT;
		errno = BENBUF;
		return -1;
	}

	/* validate arguments */
	if (i < 1 || i > bp->bufcnt) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}
#endif
	/* check block addresses */
	more = b_blockp(bp, i)->more;
	less = b_blockp(bp, i)->less;
	if (more > bp->bufcnt || less > bp->bufcnt) {
		BEPRINT;
		errno = BEPANIC;
		return -1;
	}

	/* check if already most recently used */
	if (more == 0) {
		errno = 0;
		return 0;
	}

	/* remove block i from linked list */
	b_blockp(bp, more)->less = less;
	if (less != 0) {
		b_blockp(bp, less)->more = more;
	} else {
		bp->least = more;
	}

	/* connect ith block as most recently used */
	b_blockp(bp, i)->more = 0;
	b_blockp(bp, i)->less = bp->most;
	b_blockp(bp, bp->most)->more = i;
	bp->most = i;

	errno = 0;
	return 0;
}

/*man---------------------------------------------------------------------------
NAME
     b_put - put block into block file

SYNOPSIS
     #include "blkio_.h"

     int b_put(bp, i)
     BLKFILE *bp;
     size_t i;

DESCRIPTION
     The b_put function writes a block from the ith buffer of block
     file bp to the file.  b_put writes to the block identified by
     the block number field of the block structure associated with
     buffer i (i.e., b_blockp(bp, i)->bn); the zeroth buffer is
     always used for the header.  If the write flag is not set,
     nothing is written.  After writing, the write flag is cleared.

     b_put will fail if one or more of the following is true:

     [EINVAL]       bp is not a valid block file.
     [EINVAL]       i is not in the range [0..bp->bufcnt].
     [BENBUF]       bp is not buffered.

SEE ALSO
     b_get.

DIAGNOSTICS
     Upon successful completion, a value of 0 is returned.  Otherwise,
     a value of -1 is returned, and errno set to indicate the error.

------------------------------------------------------------------------------*/
int b_put(BLKFILE *bp, size_t i)
{
#ifdef DEBUG
	/* validate arguments */
	if (!b_valid(bp)) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}

	/* check if not open */
	if (!(bp->flags & BIOOPEN)) {
		BEPRINT;
		errno = BENOPEN;
		return -1;
	}

	/* check if file is not buffered */
	if (bp->bufcnt == 0) {
		BEPRINT;
		errno = BENBUF;
		return -1;
	}

	/* validate arguments */
	if (i > bp->bufcnt) {
		BEPRINT;
		errno = EINVAL;
		return -1;
	}
#endif
	/* check if block doesn't need to be written to disk */
	if (!(b_blockp(bp, i)->flags & BLKWRITE)) {
		errno = 0;
		return 0;
	}

	/* check for inconsistent read flag setting */
	if (!(b_blockp(bp, i)->flags & BLKREAD)) {
		BEPRINT;
		errno = BEPANIC;
		return 0;
	}

	/* write block to disk */
	if (i == 0) {
		if (b_uputf(bp, (bpos_t)0, (size_t)0, b_blkbuf(bp, (size_t)0), bp->hdrsize) == -1) {
			BEPRINT;
			return -1;
		}
	} else {
		if (b_uputf(bp, b_blockp(bp, i)->bn, (size_t)0, b_blkbuf(bp, i), bp->blksize) == -1) {
			BEPRINT;
			return -1;
		}
	}

	/* clear all but read flag */
	b_blockp(bp, i)->flags = BLKREAD;

	errno = 0;
	return 0;
}

/*man---------------------------------------------------------------------------
NAME
     b_valid - validate block file pointer

SYNOPSIS
     #include "blkio_.h"

     bool b_valid(bp)
     BLKFILE *bp;

DESCRIPTION
     The b_valid function determines if bp is a valid BLKFILE pointer.
     If valid, the TRUE is returned.  If not, then FALSE is returned.

------------------------------------------------------------------------------*/
bool b_valid(const BLKFILE *bp)
{
	if (bp < biob || bp > (biob + BOPEN_MAX - 1)) {
		return FALSE;
	}
	if (((char *)bp - (char *)biob) % sizeof(*biob) != 0) {
		return FALSE;
	}

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -