Files
Yasuhiro KIMURA 9678929700 Update to 18.1.40
2020-07-24 01:10:28 +09:00

185 lines
4.5 KiB
C

/*-
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* See the file EXAMPLES-LICENSE for license information.
*
*/
#include "priority_common_utils.h"
#include "db.h"
/* Configure and open a Berkeley DB environment. */
int open_env(env, home, in_memory, create, threaded)
DB_ENV **env;
const char *home;
int in_memory;
int create;
int threaded;
{
DB_ENV *dbenv;
u_int32_t flags;
int ret;
*env = NULL;
dbenv = NULL;
/*
* Initialize the transactional, logging, locking systems
* and the cache.
*/
flags = DB_INIT_TXN|DB_INIT_LOG|DB_INIT_LOCK|DB_INIT_MPOOL;
if (create)
flags |= DB_CREATE;
if (threaded)
flags |= DB_THREAD;
if ((ret = db_env_create(&dbenv, 0)) != 0) {
printf("Error creating the BDB environment");
return ret;
}
/*
* Logging in memory will improve performance, but the system will not
* be recoverable in case of a crash.
*/
if (in_memory) {
if ((ret = dbenv->log_set_config(
dbenv, DB_LOG_IN_MEMORY, 1)) != 0)
goto err;
/*
* Logging in memory usually requires a log buffer that is
* larger than the 1 MB default. If the log buffer is too
* small then the application could run out of room for new
* logs.
*/
if ((ret = dbenv->set_lg_bsize(dbenv, 20 * 1024 * 1024)) != 0)
goto err;
} else {
/*
* Configure the environment to automatically delete logs
* that are no longer needed for standard recovery.
*/
if ((ret = dbenv->log_set_config(
dbenv, DB_LOG_AUTO_REMOVE, 1)) != 0)
goto err;
}
/*
* The cache should be large enough to hold the working data set of
* the application. When using in-memory databases the cache must be
* large enough to hold the entire database, or else an out of memory
* error can occur.
*/
if ((ret = dbenv->set_cachesize(dbenv, 0, NUM_MESSAGES * MSG_LEN, 1)) != 0)
goto err;
/* Open the environment. */
if ((ret = dbenv->open(dbenv, home, flags, 0)) != 0)
goto err;
*env = dbenv;
return 0;
err: printf("Error creating the BDB environment");
if (dbenv != NULL)
(void)dbenv->close(dbenv, 0);
return ret;
}
/* Configure and open a Berkeley DB queue database. */
int open_queue(dbenv, queue, name, in_memory, create, threaded)
DB_ENV *dbenv;
DB **queue;
const char *name;
int in_memory;
int create;
int threaded;
{
DB *msg_queue;
int ret;
u_int32_t flags;
const char *db_name, *file_name;
msg_queue = NULL;
*queue = NULL;
flags = DB_AUTO_COMMIT;
if (create)
flags |= DB_CREATE;
if (threaded)
flags |= DB_THREAD;
db_name = file_name = NULL;
/* In memory databases are faster but not persistent. */
if (in_memory)
db_name = name;
else
file_name = name;
if ((ret = db_create(&msg_queue, dbenv, 0)) != 0)
goto err;
/* The record size needs to be set when using a queue. */
if ((ret = msg_queue->set_re_len(msg_queue, MSG_LEN)) != 0)
goto err;
/*
* Optionally, unfilled space at the end of the record can be filled
* with the given character.
*/
if ((ret = msg_queue->set_re_pad(msg_queue, 0)) != 0)
goto err;
/*
* If the queue is not in memory then it will be allocated on disk
* as needed in files equal to the given extent size. The files will
* be deleted when they become empty. If no extent size is given then
* the queue will be a single file that will always be equal to the
* largest size the queue has ever been in its lifetime.
*/
if (!in_memory) {
if ((ret = msg_queue->set_q_extentsize(
msg_queue, MSG_EXTENT_SIZE)) != 0)
goto err;
}
/*
* Open the queue. In this program, if DB_CREATE is not set and the
* database does not exist, then the program sleeps for half a second
* before trying again to open the database.
*/
do {
ret = msg_queue->open(msg_queue,
NULL, file_name, db_name, DB_QUEUE, flags, 0);
if (ret == ENOENT && !create)
usleep(500);
else if (ret != 0)
goto err;
} while (ret == ENOENT);
*queue = msg_queue;
return 0;
err:
dbenv->err(dbenv, ret, "Error opening database %s: ", name);
if (msg_queue != NULL)
(void)msg_queue->close(msg_queue, 0);
return ret;
}
/* Define gettimeofday and snprintf for Windows. */
#ifdef _WIN32
#define snprintf sprintf_s
int gettimeofday(struct timeval2 *tv, struct timezone *tz)
{
struct _timeb now;
_ftime(&now);
tv->tv_sec = now.time;
tv->tv_usec = now.millitm * NS_PER_US;
return (0);
}
#endif