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

📄 rep_common.c

📁 嵌入式数据库Berkeley DB-4.5.20源代码
💻 C
字号:
/*- * See the file LICENSE for redistribution information. * * Copyright (c) 2006 *	Oracle Corporation.  All rights reserved. * * $Id: rep_common.c,v 12.13 2006/09/08 20:32:06 bostic Exp $ */#include <errno.h>#include <stdlib.h>#include <string.h>#include <db.h>#include "rep_common.h"#define	CACHESIZE	(10 * 1024 * 1024)#define	DATABASE	"quote.db"#define	SLEEPTIME	3#ifdef _WIN32#define WIN32_LEAN_AND_MEAN#include <windows.h>#define	sleep(s)		Sleep(1000 * (s))#endifstatic void event_callback __P((DB_ENV *, u_int32_t, void *));static int print_stocks __P((DB *));static voidevent_callback(dbenv, which, info)	DB_ENV *dbenv;	u_int32_t which;	void *info;{	APP_DATA *app = dbenv->app_private;	info = NULL;				/* Currently unused. */	switch (which) {	case DB_EVENT_REP_MASTER:		app->is_master = 1;		break;	case DB_EVENT_REP_CLIENT:		app->is_master = 0;		break;	case DB_EVENT_REP_STARTUPDONE: /* FALLTHROUGH */	case DB_EVENT_REP_NEWMASTER:		/* I don't care about these, for now. */		break;	default:		dbenv->errx(dbenv, "ignoring event %d", which);	}}static intprint_stocks(dbp)	DB *dbp;{	DBC *dbc;	DBT key, data;#define	MAXKEYSIZE	10#define	MAXDATASIZE	20	char keybuf[MAXKEYSIZE + 1], databuf[MAXDATASIZE + 1];	int ret, t_ret;	u_int32_t keysize, datasize; 	if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0) {		dbp->err(dbp, ret, "can't open cursor");		return (ret);	}	memset(&key, 0, sizeof(key));	memset(&data, 0, sizeof(data));	printf("\tSymbol\tPrice\n");	printf("\t======\t=====\n");	for (ret = dbc->c_get(dbc, &key, &data, DB_FIRST);	    ret == 0;	    ret = dbc->c_get(dbc, &key, &data, DB_NEXT)) {		keysize = key.size > MAXKEYSIZE ? MAXKEYSIZE : key.size;		memcpy(keybuf, key.data, keysize);		keybuf[keysize] = '\0';		datasize = data.size >= MAXDATASIZE ? MAXDATASIZE : data.size;		memcpy(databuf, data.data, datasize);		databuf[datasize] = '\0';		printf("\t%s\t%s\n", keybuf, databuf);	}	printf("\n");	fflush(stdout);	if ((t_ret = dbc->c_close(dbc)) != 0 && ret == 0)		ret = t_ret;	switch (ret) {	case 0:	case DB_NOTFOUND:	case DB_LOCK_DEADLOCK:		return (0);	default:		return (ret);	}}#define	BUFSIZE 1024intdoloop(dbenv, app_data)	DB_ENV *dbenv;	APP_DATA *app_data;{	DB *dbp;	DBT key, data;	char buf[BUFSIZE], *rbuf;	u_int32_t flags;	int ret;	dbp = NULL;	ret = 0;	memset(&key, 0, sizeof(key));	memset(&data, 0, sizeof(data));	for (;;) {		if (dbp == NULL) {			if ((ret = db_create(&dbp, dbenv, 0)) != 0)				return (ret);			/* Set page size small so page allocation is cheap. */			if ((ret = dbp->set_pagesize(dbp, 512)) != 0)				goto err;			flags = DB_AUTO_COMMIT;			if (app_data->is_master)				flags |= DB_CREATE;			if ((ret = dbp->open(dbp,			    NULL, DATABASE, NULL, DB_BTREE, flags, 0)) != 0) {				if (ret == ENOENT) {					printf(					  "No stock database yet available.\n");					if ((ret = dbp->close(dbp, 0)) != 0) {						dbenv->err(dbenv, ret,						    "DB->close");						goto err;					}					dbp = NULL;					sleep(SLEEPTIME);					continue;				}				dbenv->err(dbenv, ret, "DB->open");				goto err;			}		}		printf("QUOTESERVER%s> ",		    app_data->is_master ? "" : " (read-only)");		fflush(stdout);		if (fgets(buf, sizeof(buf), stdin) == NULL)			break;		if (strtok(&buf[0], " \t\n") == NULL) {			switch ((ret = print_stocks(dbp))) {			case 0:				continue;			case DB_REP_HANDLE_DEAD:				(void)dbp->close(dbp, DB_NOSYNC);				dbp = NULL;			default:				dbp->err(dbp, ret, "Error traversing data");				goto err;			}		}		rbuf = strtok(NULL, " \t\n");		if (rbuf == NULL || rbuf[0] == '\0') {			if (strncmp(buf, "exit", 4) == 0 ||			    strncmp(buf, "quit", 4) == 0)				break;			dbenv->errx(dbenv, "Format: TICKER VALUE");			continue;		}		if (!app_data->is_master) {			dbenv->errx(dbenv, "Can't update at client");			continue;		}		key.data = buf;		key.size = (u_int32_t)strlen(buf);		data.data = rbuf;		data.size = (u_int32_t)strlen(rbuf);		if ((ret = dbp->put(dbp,		    NULL, &key, &data, DB_AUTO_COMMIT)) != 0) {			dbp->err(dbp, ret, "DB->put");			goto err;		}	}err:	if (dbp != NULL)		(void)dbp->close(dbp, DB_NOSYNC);	return (ret);}intcreate_env(progname, dbenvp)	const char *progname;	DB_ENV **dbenvp;{	DB_ENV *dbenv;	int ret;	if ((ret = db_env_create(&dbenv, 0)) != 0) {		fprintf(stderr, "can't create env handle: %s\n",		    db_strerror(ret));		return (ret);	}	dbenv->set_errfile(dbenv, stderr);	dbenv->set_errpfx(dbenv, progname);	(void)dbenv->set_event_notify(dbenv, event_callback);	*dbenvp = dbenv;	return (0);}/* Open and configure an environment. */intenv_init(dbenv, home)	DB_ENV *dbenv;	const char *home;{	u_int32_t flags;	int ret;	(void)dbenv->set_cachesize(dbenv, 0, CACHESIZE, 0);	(void)dbenv->set_flags(dbenv, DB_TXN_NOSYNC, 1);	flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL |	    DB_INIT_REP | DB_INIT_TXN | DB_RECOVER | DB_THREAD;	if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0)		dbenv->err(dbenv, ret, "can't open environment");	return (ret);}/* * In this application, we specify all communication via the command line.  In * a real application, we would expect that information about the other sites * in the system would be maintained in some sort of configuration file.  The * critical part of this interface is that we assume at startup that we can * find out * 	1) what host/port we wish to listen on for connections, * 	2) a (possibly empty) list of other sites we should attempt to connect * 	to; and * 	3) what our Berkeley DB home environment is. * * These pieces of information are expressed by the following flags. * -m host:port (required; m stands for me) * -o host:port (optional; o stands for other; any number of these may be *	specified) * -h home directory * -n nsites (optional; number of sites in replication group; defaults to 0 *	in which case we try to dynamically compute the number of sites in *	the replication group) * -p priority (optional: defaults to 100) * -C or -M  start up as client or master (optional) */voidusage(progname)	const char *progname;{	fprintf(stderr, "usage: %s ", progname);	fprintf(stderr, "[-CM][-h home][-o host:port][-m host:port]%s",	    "[-n nsites][-p priority]\n");	exit(EXIT_FAILURE);}

⌨️ 快捷键说明

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