#include "db_config.h"
#include "db_int.h"
#include "dbinc/db_page.h"
#include "dbinc/btree.h"
#include "dbinc/qam.h"
static int __bam_set_bt_minkey __P((DB *, u_int32_t));
static int __bam_get_bt_compare
__P((DB *, int (**)(DB *, const DBT *, const DBT *)));
static int __bam_get_bt_prefix
__P((DB *, size_t(**)(DB *, const DBT *, const DBT *)));
static int __bam_set_bt_prefix
__P((DB *, size_t(*)(DB *, const DBT *, const DBT *)));
static int __bam_get_bt_compress __P((DB *,
int (**)(DB *, const DBT *, const DBT *, const DBT *, const DBT *, DBT *),
int (**)(DB *, const DBT *, const DBT *, DBT *, DBT *, DBT *)));
static int __ram_get_re_delim __P((DB *, int *));
static int __ram_set_re_delim __P((DB *, int));
static int __ram_set_re_len __P((DB *, u_int32_t));
static int __ram_set_re_pad __P((DB *, int));
static int __ram_get_re_source __P((DB *, const char **));
static int __ram_set_re_source __P((DB *, const char *));
int
__bam_db_create(dbp)
DB *dbp;
{
BTREE *t;
int ret;
if ((ret = __os_calloc(dbp->env, 1, sizeof(BTREE), &t)) != 0)
return (ret);
dbp->bt_internal = t;
t->bt_minkey = DEFMINKEYPAGE;
t->bt_compare = __bam_defcmp;
t->bt_prefix = __bam_defpfx;
#ifdef HAVE_COMPRESSION
t->bt_compress = NULL;
t->bt_decompress = NULL;
t->compress_dup_compare = NULL;
if (F_ISSET(dbp, DB_AM_COMPRESS) &&
(ret = __bam_set_bt_compress(dbp, NULL, NULL)) != 0)
return (ret);
#endif
dbp->get_bt_compare = __bam_get_bt_compare;
dbp->set_bt_compare = __bam_set_bt_compare;
dbp->get_bt_minkey = __bam_get_bt_minkey;
dbp->set_bt_minkey = __bam_set_bt_minkey;
dbp->get_bt_prefix = __bam_get_bt_prefix;
dbp->set_bt_prefix = __bam_set_bt_prefix;
dbp->get_bt_compress = __bam_get_bt_compress;
dbp->set_bt_compress = __bam_set_bt_compress;
t->re_pad = ' ';
t->re_delim = '\n';
t->re_eof = 1;
dbp->get_re_delim = __ram_get_re_delim;
dbp->set_re_delim = __ram_set_re_delim;
dbp->get_re_len = __ram_get_re_len;
dbp->set_re_len = __ram_set_re_len;
dbp->get_re_pad = __ram_get_re_pad;
dbp->set_re_pad = __ram_set_re_pad;
dbp->get_re_source = __ram_get_re_source;
dbp->set_re_source = __ram_set_re_source;
return (0);
}
int
__bam_db_close(dbp)
DB *dbp;
{
BTREE *t;
if ((t = dbp->bt_internal) == NULL)
return (0);
if (t->re_fp != NULL)
(void)fclose(t->re_fp);
if (t->re_source != NULL)
__os_free(dbp->env, t->re_source);
__os_free(dbp->env, t);
dbp->bt_internal = NULL;
return (0);
}
void
__bam_map_flags(dbp, inflagsp, outflagsp)
DB *dbp;
u_int32_t *inflagsp, *outflagsp;
{
COMPQUIET(dbp, NULL);
if (FLD_ISSET(*inflagsp, DB_DUP)) {
FLD_SET(*outflagsp, DB_AM_DUP);
FLD_CLR(*inflagsp, DB_DUP);
}
if (FLD_ISSET(*inflagsp, DB_DUPSORT)) {
FLD_SET(*outflagsp, DB_AM_DUP | DB_AM_DUPSORT);
FLD_CLR(*inflagsp, DB_DUPSORT);
}
if (FLD_ISSET(*inflagsp, DB_RECNUM)) {
FLD_SET(*outflagsp, DB_AM_RECNUM);
FLD_CLR(*inflagsp, DB_RECNUM);
}
if (FLD_ISSET(*inflagsp, DB_REVSPLITOFF)) {
FLD_SET(*outflagsp, DB_AM_REVSPLITOFF);
FLD_CLR(*inflagsp, DB_REVSPLITOFF);
}
}
int
__bam_set_flags(dbp, flagsp)
DB *dbp;
u_int32_t *flagsp;
{
BTREE *t;
u_int32_t flags;
t = dbp->bt_internal;
flags = *flagsp;
if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF))
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags");
if (LF_ISSET(DB_DUP | DB_DUPSORT))
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
if (LF_ISSET(DB_RECNUM | DB_REVSPLITOFF))
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH);
if (LF_ISSET(DB_DUP | DB_DUPSORT) && F_ISSET(dbp, DB_AM_RECNUM))
goto incompat;
if (LF_ISSET(DB_RECNUM) && F_ISSET(dbp, DB_AM_DUP))
goto incompat;
if (LF_ISSET(DB_RECNUM) && LF_ISSET(DB_DUP | DB_DUPSORT))
goto incompat;
#ifdef HAVE_COMPRESSION
if (LF_ISSET(DB_RECNUM) && DB_IS_COMPRESSED(dbp)) {
__db_errx(dbp->env, DB_STR("1024",
"DB_RECNUM cannot be used with compression"));
return (EINVAL);
}
if (LF_ISSET(DB_DUP) && !LF_ISSET(DB_DUPSORT) &&
!F_ISSET(dbp, DB_AM_DUPSORT) && DB_IS_COMPRESSED(dbp)) {
__db_errx(dbp->env, DB_STR("1025",
"DB_DUP cannot be used with compression without DB_DUPSORT"));
return (EINVAL);
}
#endif
if (LF_ISSET(DB_DUPSORT) && dbp->dup_compare == NULL) {
#ifdef HAVE_COMPRESSION
if (DB_IS_COMPRESSED(dbp)) {
dbp->dup_compare = __bam_compress_dupcmp;
t->compress_dup_compare = __bam_defcmp;
} else
#endif
dbp->dup_compare = __bam_defcmp;
}
__bam_map_flags(dbp, flagsp, &dbp->flags);
return (0);
incompat:
return (__db_ferr(dbp->env, "DB->set_flags", 1));
}
static int
__bam_get_bt_compare(dbp, funcp)
DB *dbp;
int (**funcp) __P((DB *, const DBT *, const DBT *));
{
BTREE *t;
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
if (funcp != NULL)
*funcp = t->bt_compare;
return (0);
}
int
__bam_set_bt_compare(dbp, func)
DB *dbp;
int (*func) __P((DB *, const DBT *, const DBT *));
{
BTREE *t;
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compare");
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
t->bt_compare = func;
if (t->bt_prefix == __bam_defpfx)
t->bt_prefix = NULL;
return (0);
}
static int
__bam_get_bt_compress(dbp, compressp, decompressp)
DB *dbp;
int (**compressp) __P((DB *, const DBT *, const DBT *, const DBT *,
const DBT *, DBT *));
int (**decompressp) __P((DB *, const DBT *, const DBT *, DBT *, DBT *,
DBT *));
{
#ifdef HAVE_COMPRESSION
BTREE *t;
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
if (compressp != NULL)
*compressp = t->bt_compress;
if (decompressp != NULL)
*decompressp = t->bt_decompress;
return (0);
#else
COMPQUIET(compressp, NULL);
COMPQUIET(decompressp, NULL);
__db_errx(dbp->env, DB_STR("1026",
"compression support has not been compiled in"));
return (EINVAL);
#endif
}
int
__bam_set_bt_compress(dbp, compress, decompress)
DB *dbp;
int (*compress) __P((DB *, const DBT *, const DBT *, const DBT *,
const DBT *, DBT *));
int (*decompress) __P((DB *, const DBT *, const DBT *, DBT *, DBT *,
DBT *));
{
#ifdef HAVE_COMPRESSION
BTREE *t;
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_compress");
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
if (F_ISSET(dbp, DB_AM_RECNUM)) {
__db_errx(dbp->env, DB_STR("1027",
"compression cannot be used with DB_RECNUM"));
return (EINVAL);
}
if (F_ISSET(dbp, DB_AM_DUP) && !F_ISSET(dbp, DB_AM_DUPSORT)) {
__db_errx(dbp->env, DB_STR("1028",
"compression cannot be used with DB_DUP without DB_DUPSORT"));
return (EINVAL);
}
if (compress != 0 && decompress != 0) {
t->bt_compress = compress;
t->bt_decompress = decompress;
} else if (compress == 0 && decompress == 0) {
t->bt_compress = __bam_defcompress;
t->bt_decompress = __bam_defdecompress;
} else {
__db_errx(dbp->env, DB_STR("1029",
"to enable compression you need to supply both function arguments"));
return (EINVAL);
}
F_SET(dbp, DB_AM_COMPRESS);
if (F_ISSET(dbp, DB_AM_DUPSORT)) {
t->compress_dup_compare = dbp->dup_compare;
dbp->dup_compare = __bam_compress_dupcmp;
}
return (0);
#else
COMPQUIET(compress, NULL);
COMPQUIET(decompress, NULL);
__db_errx(dbp->env, DB_STR("1030",
"compression support has not been compiled in"));
return (EINVAL);
#endif
}
int
__bam_get_bt_minkey(dbp, bt_minkeyp)
DB *dbp;
u_int32_t *bt_minkeyp;
{
BTREE *t;
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
*bt_minkeyp = t->bt_minkey;
return (0);
}
static int
__bam_set_bt_minkey(dbp, bt_minkey)
DB *dbp;
u_int32_t bt_minkey;
{
BTREE *t;
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_minkey");
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
if (bt_minkey < 2) {
__db_errx(dbp->env, DB_STR("1031",
"minimum bt_minkey value is 2"));
return (EINVAL);
}
t->bt_minkey = bt_minkey;
return (0);
}
static int
__bam_get_bt_prefix(dbp, funcp)
DB *dbp;
size_t (**funcp) __P((DB *, const DBT *, const DBT *));
{
BTREE *t;
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
if (funcp != NULL)
*funcp = t->bt_prefix;
return (0);
}
static int
__bam_set_bt_prefix(dbp, func)
DB *dbp;
size_t (*func) __P((DB *, const DBT *, const DBT *));
{
BTREE *t;
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_bt_prefix");
DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE);
t = dbp->bt_internal;
t->bt_prefix = func;
return (0);
}
void
__bam_copy_config(src, dst, nparts)
DB *src, *dst;
u_int32_t nparts;
{
BTREE *s, *d;
COMPQUIET(nparts, 0);
s = src->bt_internal;
d = dst->bt_internal;
d->bt_compare = s->bt_compare;
d->bt_minkey = s->bt_minkey;
d->bt_minkey = s->bt_minkey;
d->bt_prefix = s->bt_prefix;
#ifdef HAVE_COMPRESSION
d->bt_compress = s->bt_compress;
d->bt_decompress = s->bt_decompress;
d->compress_dup_compare = s->compress_dup_compare;
#endif
}
void
__ram_map_flags(dbp, inflagsp, outflagsp)
DB *dbp;
u_int32_t *inflagsp, *outflagsp;
{
COMPQUIET(dbp, NULL);
if (FLD_ISSET(*inflagsp, DB_RENUMBER)) {
FLD_SET(*outflagsp, DB_AM_RENUMBER);
FLD_CLR(*inflagsp, DB_RENUMBER);
}
if (FLD_ISSET(*inflagsp, DB_SNAPSHOT)) {
FLD_SET(*outflagsp, DB_AM_SNAPSHOT);
FLD_CLR(*inflagsp, DB_SNAPSHOT);
}
}
int
__ram_set_flags(dbp, flagsp)
DB *dbp;
u_int32_t *flagsp;
{
u_int32_t flags;
flags = *flagsp;
if (LF_ISSET(DB_RENUMBER | DB_SNAPSHOT)) {
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags");
DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
}
__ram_map_flags(dbp, flagsp, &dbp->flags);
return (0);
}
static int
__ram_get_re_delim(dbp, re_delimp)
DB *dbp;
int *re_delimp;
{
BTREE *t;
DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
t = dbp->bt_internal;
*re_delimp = t->re_delim;
return (0);
}
static int
__ram_set_re_delim(dbp, re_delim)
DB *dbp;
int re_delim;
{
BTREE *t;
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_delim");
DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
t = dbp->bt_internal;
t->re_delim = re_delim;
F_SET(dbp, DB_AM_DELIMITER);
return (0);
}
int
__ram_get_re_len(dbp, re_lenp)
DB *dbp;
u_int32_t *re_lenp;
{
BTREE *t;
QUEUE *q;
DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
if (dbp->type == DB_QUEUE) {
q = dbp->q_internal;
*re_lenp = q->re_len;
} else {
t = dbp->bt_internal;
*re_lenp = t->re_len;
}
return (0);
}
static int
__ram_set_re_len(dbp, re_len)
DB *dbp;
u_int32_t re_len;
{
BTREE *t;
#ifdef HAVE_QUEUE
QUEUE *q;
#endif
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_len");
DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
t = dbp->bt_internal;
t->re_len = re_len;
#ifdef HAVE_QUEUE
q = dbp->q_internal;
q->re_len = re_len;
#endif
F_SET(dbp, DB_AM_FIXEDLEN);
return (0);
}
int
__ram_get_re_pad(dbp, re_padp)
DB *dbp;
int *re_padp;
{
BTREE *t;
QUEUE *q;
DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
if (dbp->type == DB_QUEUE) {
q = dbp->q_internal;
*re_padp = q->re_pad;
} else {
t = dbp->bt_internal;
*re_padp = t->re_pad;
}
return (0);
}
static int
__ram_set_re_pad(dbp, re_pad)
DB *dbp;
int re_pad;
{
BTREE *t;
#ifdef HAVE_QUEUE
QUEUE *q;
#endif
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_pad");
DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO);
t = dbp->bt_internal;
t->re_pad = re_pad;
#ifdef HAVE_QUEUE
q = dbp->q_internal;
q->re_pad = re_pad;
#endif
F_SET(dbp, DB_AM_PAD);
return (0);
}
static int
__ram_get_re_source(dbp, re_sourcep)
DB *dbp;
const char **re_sourcep;
{
BTREE *t;
DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
t = dbp->bt_internal;
*re_sourcep = t->re_source;
return (0);
}
static int
__ram_set_re_source(dbp, re_source)
DB *dbp;
const char *re_source;
{
BTREE *t;
DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_re_source");
DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO);
t = dbp->bt_internal;
return (__os_strdup(dbp->env, re_source, &t->re_source));
}