/*- * See the file LICENSE for redistribution information. * * Copyright (c) 1999, 2000 * Sleepycat Software. All rights reserved. */ #include "db_config.h" #ifndef lint static const char revid[] = "$Id: bt_method.c,v 11.20 2000/11/30 00:58:28 ubell Exp $"; #endif /* not lint */ #ifndef NO_SYSTEM_INCLUDES #include #endif #include "db_int.h" #include "db_page.h" #include "btree.h" #include "qam.h" static int __bam_set_bt_compare __P((DB *, int (*)(DB *, const DBT *, const DBT *))); static int __bam_set_bt_maxkey __P((DB *, u_int32_t)); static int __bam_set_bt_minkey __P((DB *, u_int32_t)); static int __bam_set_bt_prefix __P((DB *, size_t(*)(DB *, const DBT *, const DBT *))); 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_set_re_source __P((DB *, const char *)); /* * __bam_db_create -- * Btree specific initialization of the DB structure. * * PUBLIC: int __bam_db_create __P((DB *)); */ int __bam_db_create(dbp) DB *dbp; { BTREE *t; int ret; /* Allocate and initialize the private btree structure. */ if ((ret = __os_calloc(dbp->dbenv, 1, sizeof(BTREE), &t)) != 0) return (ret); dbp->bt_internal = t; t->bt_minkey = DEFMINKEYPAGE; /* Btree */ t->bt_compare = __bam_defcmp; t->bt_prefix = __bam_defpfx; dbp->set_bt_compare = __bam_set_bt_compare; dbp->set_bt_maxkey = __bam_set_bt_maxkey; dbp->set_bt_minkey = __bam_set_bt_minkey; dbp->set_bt_prefix = __bam_set_bt_prefix; t->re_pad = ' '; /* Recno */ t->re_delim = '\n'; t->re_eof = 1; dbp->set_re_delim = __ram_set_re_delim; dbp->set_re_len = __ram_set_re_len; dbp->set_re_pad = __ram_set_re_pad; dbp->set_re_source = __ram_set_re_source; return (0); } /* * __bam_db_close -- * Btree specific discard of the DB structure. * * PUBLIC: int __bam_db_close __P((DB *)); */ int __bam_db_close(dbp) DB *dbp; { BTREE *t; t = dbp->bt_internal; /* Recno */ /* Close any backing source file descriptor. */ if (t->re_fp != NULL) (void)fclose(t->re_fp); /* Free any backing source file name. */ if (t->re_source != NULL) __os_freestr(t->re_source); __os_free(t, sizeof(BTREE)); dbp->bt_internal = NULL; return (0); } /* * __bam_set_flags -- * Set Btree specific flags. * * PUBLIC: int __bam_set_flags __P((DB *, u_int32_t *flagsp)); */ int __bam_set_flags(dbp, flagsp) DB *dbp; u_int32_t *flagsp; { u_int32_t flags; flags = *flagsp; if (LF_ISSET(DB_DUP | DB_DUPSORT | DB_RECNUM | DB_REVSPLITOFF)) { DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_flags"); /* * The DB_DUP and DB_DUPSORT flags are shared by the Hash * and Btree access methods. */ 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); if (LF_ISSET(DB_DUP | DB_DUPSORT)) { /* DB_DUP/DB_DUPSORT is incompatible with DB_RECNUM. */ if (F_ISSET(dbp, DB_BT_RECNUM)) goto incompat; if (LF_ISSET(DB_DUPSORT)) { if (dbp->dup_compare == NULL) dbp->dup_compare = __bam_defcmp; F_SET(dbp, DB_AM_DUPSORT); } F_SET(dbp, DB_AM_DUP); LF_CLR(DB_DUP | DB_DUPSORT); } if (LF_ISSET(DB_RECNUM)) { /* DB_RECNUM is incompatible with DB_DUP/DB_DUPSORT. */ if (F_ISSET(dbp, DB_AM_DUP)) goto incompat; F_SET(dbp, DB_BT_RECNUM); LF_CLR(DB_RECNUM); } if (LF_ISSET(DB_REVSPLITOFF)) { F_SET(dbp, DB_BT_REVSPLIT); LF_CLR(DB_REVSPLITOFF); } *flagsp = flags; } return (0); incompat: return (__db_ferr(dbp->dbenv, "DB->set_flags", 1)); } /* * __bam_set_bt_compare -- * Set the comparison function. */ static int __bam_set_bt_compare(dbp, func) DB *dbp; int (*func) __P((DB *, const DBT *, const DBT *)); { BTREE *t; DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_compare"); DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); t = dbp->bt_internal; /* * Can't default the prefix routine if the user supplies a comparison * routine; shortening the keys can break their comparison algorithm. */ t->bt_compare = func; if (t->bt_prefix == __bam_defpfx) t->bt_prefix = NULL; return (0); } /* * __bam_set_bt_maxkey -- * Set the maximum keys per page. */ static int __bam_set_bt_maxkey(dbp, bt_maxkey) DB *dbp; u_int32_t bt_maxkey; { BTREE *t; DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_maxkey"); DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); t = dbp->bt_internal; if (bt_maxkey < 1) { __db_err(dbp->dbenv, "minimum bt_maxkey value is 1"); return (EINVAL); } t->bt_maxkey = bt_maxkey; return (0); } /* * __bam_set_bt_minkey -- * Set the minimum keys per page. */ static int __bam_set_bt_minkey(dbp, bt_minkey) DB *dbp; u_int32_t bt_minkey; { BTREE *t; DB_ILLEGAL_AFTER_OPEN(dbp, "set_bt_minkey"); DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); t = dbp->bt_internal; if (bt_minkey < 2) { __db_err(dbp->dbenv, "minimum bt_minkey value is 2"); return (EINVAL); } t->bt_minkey = bt_minkey; return (0); } /* * __bam_set_bt_prefix -- * Set the prefix function. */ 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, "set_bt_prefix"); DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE); t = dbp->bt_internal; t->bt_prefix = func; return (0); } /* * __ram_set_flags -- * Set Recno specific flags. * * PUBLIC: int __ram_set_flags __P((DB *, u_int32_t *flagsp)); */ 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); if (LF_ISSET(DB_RENUMBER)) { F_SET(dbp, DB_RE_RENUMBER); LF_CLR(DB_RENUMBER); } if (LF_ISSET(DB_SNAPSHOT)) { F_SET(dbp, DB_RE_SNAPSHOT); LF_CLR(DB_SNAPSHOT); } *flagsp = flags; } return (0); } /* * __ram_set_re_delim -- * Set the variable-length input record delimiter. */ static int __ram_set_re_delim(dbp, re_delim) DB *dbp; int re_delim; { BTREE *t; DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_delim"); DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); t = dbp->bt_internal; t->re_delim = re_delim; F_SET(dbp, DB_RE_DELIMITER); return (0); } /* * __ram_set_re_len -- * Set the variable-length input record length. */ static int __ram_set_re_len(dbp, re_len) DB *dbp; u_int32_t re_len; { BTREE *t; QUEUE *q; DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_len"); DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); t = dbp->bt_internal; t->re_len = re_len; q = dbp->q_internal; q->re_len = re_len; F_SET(dbp, DB_RE_FIXEDLEN); return (0); } /* * __ram_set_re_pad -- * Set the fixed-length record pad character. */ static int __ram_set_re_pad(dbp, re_pad) DB *dbp; int re_pad; { BTREE *t; QUEUE *q; DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_pad"); DB_ILLEGAL_METHOD(dbp, DB_OK_QUEUE | DB_OK_RECNO); t = dbp->bt_internal; t->re_pad = re_pad; q = dbp->q_internal; q->re_pad = re_pad; F_SET(dbp, DB_RE_PAD); return (0); } /* * __ram_set_re_source -- * Set the backing source file name. */ static int __ram_set_re_source(dbp, re_source) DB *dbp; const char *re_source; { BTREE *t; DB_ILLEGAL_AFTER_OPEN(dbp, "set_re_source"); DB_ILLEGAL_METHOD(dbp, DB_OK_RECNO); t = dbp->bt_internal; return (__os_strdup(dbp->dbenv, re_source, &t->re_source)); }