/*
 * Copyright (c) 2002-2005 Sendmail, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 *
 *	$Id: edb-int.h,v 1.25 2006/12/29 03:14:26 ca Exp $
 */

#ifndef SM_EDB_INT_H
#define SM_EDB_INT_H 1

#include "sm/generic.h"
#include "sm/magic.h"
#include "sm/error.h"
#include "sm/memops.h"
#include "sm/assert.h"
#include "sm/edb.h"
#include "sm/log.h"

#ifndef EDB_DEBUG
# define EDB_DEBUG	0
#endif

#if EDB_DEBUG
# define EDB_DPRINTF(x)	sm_io_fprintf x
#else
# define EDB_DPRINTF(x)
#endif

/*
**  EDB context
**  This structure contains all information for DEFEDB.
**
**  It contains a write request list which stores a list of EDB requests
**  (see above).
**
**  Notes:
**  - functions can create their own request lists which is passed
**	to the various edb_ functions: if it is NULL then edb_reql_wr
**	is used otherwise the parameter.
**  - write requests must be (partially) ordered, i.e., if two
**	request lists contain updates for the same item (TA/RCPT),
**	then their order must be preserved.  This order must be
**	enforced by the application, it can't rely on the scheduler
**	(since this is a multi-threaded program).
**	To simplify implementation, a strict ordering is required
**	(for now).
**	How to enforce ordering?
**	Have a list of request lists... (fixed size?)
**	simple algorithm:
**	give each request list a number
**	store the first and last active number here
**	if a request comes in, compare the number with first
**	while rq_number != first: wait
**	if rq_number == first: write
**	use a mutex and a condition variable
*/

struct edb_ctx_S
{
	sm_magic_T      sm_magic;
	pthread_mutex_t edb_mutex;     /* only one mutex for now */
	uint            edb_entries;   /* current number of entries */
#if 0
	sm_rcb_P        edb_rd_rcb;
#endif

	edb_req_hd_T    edb_reql_wr;   /* request list (wr) */

	/* checkpoint data: minimum KBytes, delay (s) */
	uint32_t        edb_chkpt_kb;
	uint32_t        edb_chkpt_delay;

	/* number of writes since last checkpoint */
	uint32_t        edb_writes;
#if 0
	time_T          edb_last_write;
#endif
	char            edb_pfx[8];    /* error prefix "errpfx" for BDB */
	sm_log_ctx_P    edb_lctx;      /* logging context */

	/*
	**  Pool of edb_req(uests) for reuse.
	**  Possible optimizations:
	**  - Preallocate some entries
	**  - If there are more than U(pper) entries, free some
	**    such that only L(ower) are in the list.
	*/

	edb_req_hd_T    edb_reql_fls;  /* small requests */
	edb_req_hd_T    edb_reql_fln;  /* normal (large) requests */
#if SM_REQL_FLE
	edb_req_hd_T    edb_reql_fle;  /* "emergency" (large) requests */
#endif
	DB_ENV         *edb_bdbenv;
	DB             *edb_bdb;       /* Berkeley DB */
};

/* current version (16 bits major/8 bits minor/8 bits patchlevel) */
#define EDB_VERSION	0x00010300
#define EDB_VRS_MAJ(v)	((v) & 0x7FFF0000)
#define EDB_VRS_MIN(v)	((v) & 0x0000FF00)
#define EDB_VRS_PL(v)	((v) & 0x000000FF)
#define EDB_VRS_COMPAT(new, old) (((new) == (old)) ||		\
		(EDB_VRS_MAJ(new) == EDB_VRS_MAJ(old) &&	\
		 EDB_VRS_MIN(new) >= EDB_VRS_MIN(old)))

#define EDB_VRS_KEY	"EDB_VERSION"

sm_ret_T edb_reqls_free(edb_ctx_P _edb_ctx);

#define SM_IS_EDB_CTX(edb_ctx)	SM_REQUIRE_ISA((edb_ctx), SM_EDB_CTX_MAGIC)

#endif /* ! SM_EDB_INT_H */


syntax highlighted by Code2HTML, v. 0.9.1