mirror of
https://github.com/yasuhirokimura/db18
synced 2026-06-08 18:29:23 +00:00
185 lines
4.5 KiB
C
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
|
|
|
|
|