#include "db_config.h"
#ifndef lint
static const char revid[] = "$Id: mp_method.c,v 1.2 2004/03/30 01:23:44 jtownsen Exp $";
#endif
#ifndef NO_SYSTEM_INCLUDES
#include <sys/types.h>
#ifdef HAVE_RPC
#include <rpc/rpc.h>
#endif
#include <string.h>
#endif
#include "db_int.h"
#include "dbinc/db_shash.h"
#include "dbinc/mp.h"
#ifdef HAVE_RPC
#include "dbinc_auto/db_server.h"
#include "dbinc_auto/rpc_client_ext.h"
#endif
static int __memp_get_mp_maxwrite __P((DB_ENV *, int *, int *));
static int __memp_set_mp_maxwrite __P((DB_ENV *, int, int));
static int __memp_get_mp_mmapsize __P((DB_ENV *, size_t *));
void
__memp_dbenv_create(dbenv)
DB_ENV *dbenv;
{
dbenv->mp_bytes =
32 * ((8 * 1024) + sizeof(BH)) + 37 * sizeof(DB_MPOOL_HASH);
dbenv->mp_ncache = 1;
#ifdef HAVE_RPC
if (F_ISSET(dbenv, DB_ENV_RPCCLIENT)) {
dbenv->get_cachesize = __dbcl_env_get_cachesize;
dbenv->set_cachesize = __dbcl_env_cachesize;
dbenv->get_mp_maxwrite = __dbcl_get_mp_maxwrite;
dbenv->set_mp_maxwrite = __dbcl_set_mp_maxwrite;
dbenv->get_mp_mmapsize = __dbcl_get_mp_mmapsize;
dbenv->set_mp_mmapsize = __dbcl_set_mp_mmapsize;
dbenv->memp_dump_region = NULL;
dbenv->memp_register = __dbcl_memp_register;
dbenv->memp_stat = __dbcl_memp_stat;
dbenv->memp_sync = __dbcl_memp_sync;
dbenv->memp_trickle = __dbcl_memp_trickle;
} else
#endif
{
dbenv->get_cachesize = __memp_get_cachesize;
dbenv->set_cachesize = __memp_set_cachesize;
dbenv->get_mp_maxwrite = __memp_get_mp_maxwrite;
dbenv->set_mp_maxwrite = __memp_set_mp_maxwrite;
dbenv->get_mp_mmapsize = __memp_get_mp_mmapsize;
dbenv->set_mp_mmapsize = __memp_set_mp_mmapsize;
dbenv->memp_dump_region = __memp_dump_region;
dbenv->memp_register = __memp_register_pp;
dbenv->memp_stat = __memp_stat_pp;
dbenv->memp_sync = __memp_sync_pp;
dbenv->memp_trickle = __memp_trickle_pp;
}
dbenv->memp_fcreate = __memp_fcreate_pp;
}
int
__memp_get_cachesize(dbenv, gbytesp, bytesp, ncachep)
DB_ENV *dbenv;
u_int32_t *gbytesp, *bytesp;
int *ncachep;
{
if (gbytesp != NULL)
*gbytesp = dbenv->mp_gbytes;
if (bytesp != NULL)
*bytesp = dbenv->mp_bytes;
if (ncachep != NULL)
*ncachep = dbenv->mp_ncache;
return (0);
}
int
__memp_set_cachesize(dbenv, gbytes, bytes, ncache)
DB_ENV *dbenv;
u_int32_t gbytes, bytes;
int ncache;
{
ENV_ILLEGAL_AFTER_OPEN(dbenv, "DB_ENV->set_cachesize");
if (ncache == 0)
ncache = 1;
if (gbytes / ncache == 4 && bytes == 0) {
--gbytes;
bytes = GIGABYTE - 1;
} else {
gbytes += bytes / GIGABYTE;
bytes %= GIGABYTE;
}
if (gbytes / ncache > 4 || (gbytes / ncache == 4 && bytes != 0)) {
__db_err(dbenv, "individual cache size too large");
return (EINVAL);
}
if (gbytes == 0) {
if (bytes < 500 * MEGABYTE)
bytes += (bytes / 4) + 37 * sizeof(DB_MPOOL_HASH);
if (bytes / ncache < DB_CACHESIZE_MIN)
bytes = ncache * DB_CACHESIZE_MIN;
}
dbenv->mp_gbytes = gbytes;
dbenv->mp_bytes = bytes;
dbenv->mp_ncache = ncache;
return (0);
}
static int
__memp_get_mp_maxwrite(dbenv, maxwritep, maxwrite_sleepp)
DB_ENV *dbenv;
int *maxwritep, *maxwrite_sleepp;
{
*maxwritep = dbenv->mp_maxwrite;
*maxwrite_sleepp = dbenv->mp_maxwrite_sleep;
return (0);
}
static int
__memp_set_mp_maxwrite(dbenv, maxwrite, maxwrite_sleep)
DB_ENV *dbenv;
int maxwrite, maxwrite_sleep;
{
dbenv->mp_maxwrite = maxwrite;
dbenv->mp_maxwrite_sleep = maxwrite_sleep;
return (0);
}
static int
__memp_get_mp_mmapsize(dbenv, mp_mmapsizep)
DB_ENV *dbenv;
size_t *mp_mmapsizep;
{
*mp_mmapsizep = dbenv->mp_mmapsize;
return (0);
}
int
__memp_set_mp_mmapsize(dbenv, mp_mmapsize)
DB_ENV *dbenv;
size_t mp_mmapsize;
{
dbenv->mp_mmapsize = mp_mmapsize;
return (0);
}
int
__memp_nameop(dbenv, fileid, newname, fullold, fullnew)
DB_ENV *dbenv;
u_int8_t *fileid;
const char *newname, *fullold, *fullnew;
{
DB_MPOOL *dbmp;
MPOOL *mp;
MPOOLFILE *mfp;
roff_t newname_off;
int locked, ret;
void *p;
locked = 0;
dbmp = NULL;
if (!MPOOL_ON(dbenv))
goto fsop;
dbmp = dbenv->mp_handle;
mp = dbmp->reginfo[0].primary;
if (newname == NULL)
p = NULL;
else {
if ((ret = __memp_alloc(dbmp, dbmp->reginfo,
NULL, strlen(newname) + 1, &newname_off, &p)) != 0)
return (ret);
memcpy(p, newname, strlen(newname) + 1);
}
locked = 1;
R_LOCK(dbenv, dbmp->reginfo);
for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile);
mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
if (mfp->deadfile || F_ISSET(mfp, MP_TEMP))
continue;
if (memcmp(fileid, R_ADDR(
dbmp->reginfo, mfp->fileid_off), DB_FILE_ID_LEN) != 0)
continue;
if (newname == NULL) {
MUTEX_LOCK(dbenv, &mfp->mutex);
mfp->deadfile = 1;
MUTEX_UNLOCK(dbenv, &mfp->mutex);
} else {
p = R_ADDR(dbmp->reginfo, mfp->path_off);
mfp->path_off = newname_off;
}
break;
}
if (p != NULL)
__db_shalloc_free(dbmp->reginfo[0].addr, p);
fsop: if (newname == NULL)
ret = __os_unlink(dbenv, fullold);
else
ret = __os_rename(dbenv, fullold, fullnew, 1);
if (locked)
R_UNLOCK(dbenv, dbmp->reginfo);
return (ret);
}
int
__memp_get_refcnt(dbenv, fileid, refp)
DB_ENV *dbenv;
u_int8_t *fileid;
int *refp;
{
DB_MPOOL *dbmp;
MPOOL *mp;
MPOOLFILE *mfp;
*refp = 0;
if (!MPOOL_ON(dbenv))
return (0);
dbmp = dbenv->mp_handle;
mp = dbmp->reginfo[0].primary;
R_LOCK(dbenv, dbmp->reginfo);
for (mfp = SH_TAILQ_FIRST(&mp->mpfq, __mpoolfile);
mfp != NULL; mfp = SH_TAILQ_NEXT(mfp, q, __mpoolfile)) {
if (mfp->deadfile || F_ISSET(mfp, MP_TEMP))
continue;
if (memcmp(fileid, R_ADDR(
dbmp->reginfo, mfp->fileid_off), DB_FILE_ID_LEN) != 0)
continue;
*refp = mfp->mpf_cnt;
break;
}
R_UNLOCK(dbenv, dbmp->reginfo);
return (0);
}