diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2015-02-17 17:25:57 +0000 |
---|---|---|
committer | <> | 2015-03-17 16:26:24 +0000 |
commit | 780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch) | |
tree | 598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/db/db_method.c | |
parent | 7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff) | |
download | berkeleydb-master.tar.gz |
Diffstat (limited to 'src/db/db_method.c')
-rw-r--r-- | src/db/db_method.c | 225 |
1 files changed, 214 insertions, 11 deletions
diff --git a/src/db/db_method.c b/src/db/db_method.c index 82d03e5f..d807bab6 100644 --- a/src/db/db_method.c +++ b/src/db/db_method.c @@ -1,7 +1,7 @@ /*- * See the file LICENSE for redistribution information. * - * Copyright (c) 1999, 2012 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2015 Oracle and/or its affiliates. All rights reserved. * * $Id$ */ @@ -9,6 +9,7 @@ #include "db_config.h" #include "db_int.h" +#include "dbinc/blob.h" #include "dbinc/crypto.h" #include "dbinc/db_page.h" #include "dbinc/btree.h" @@ -36,14 +37,15 @@ static int __db_set_alloc __P((DB *, void *(*)(size_t), static int __db_get_append_recno __P((DB *, int (**)(DB *, DBT *, db_recno_t))); static int __db_set_append_recno __P((DB *, int (*)(DB *, DBT *, db_recno_t))); +static int __db_get_blob_dir __P((DB *, const char **)); +static int __db_set_blob_dir __P((DB *, const char *)); +static int __db_get_blob_sub_dir __P((DB *, const char **)); static int __db_get_cachesize __P((DB *, u_int32_t *, u_int32_t *, int *)); static int __db_set_cachesize __P((DB *, u_int32_t, u_int32_t, int)); static int __db_get_create_dir __P((DB *, const char **)); static int __db_set_create_dir __P((DB *, const char *)); static int __db_get_dup_compare - __P((DB *, int (**)(DB *, const DBT *, const DBT *))); -static int __db_set_dup_compare - __P((DB *, int (*)(DB *, const DBT *, const DBT *))); + __P((DB *, int (**)(DB *, const DBT *, const DBT *, size_t *))); static int __db_get_encrypt_flags __P((DB *, u_int32_t *)); static int __db_set_encrypt __P((DB *, const char *, u_int32_t)); static int __db_get_feedback __P((DB *, void (**)(DB *, int, int))); @@ -90,6 +92,12 @@ db_create(dbpp, dbenv, flags) ip = NULL; env = dbenv == NULL ? NULL : dbenv->env; +#ifdef HAVE_ERROR_HISTORY + /* Call thread local storage initializer at least once per process. */ + if (env == NULL) + __db_thread_init(); +#endif + /* Check for invalid function flags. */ switch (flags) { case 0: @@ -206,12 +214,11 @@ __db_create_internal(dbpp, env, flags) err: if (dbp != NULL) { if (dbp->mpf != NULL) (void)__memp_fclose(dbp->mpf, 0); + if (F_ISSET(env, ENV_DBLOCAL)) + (void)__env_close(dbp->dbenv, 0); __os_free(env, dbp); } - if (dbp != NULL && F_ISSET(env, ENV_DBLOCAL)) - (void)__env_close(dbp->dbenv, 0); - return (ret); } @@ -225,6 +232,7 @@ __db_init(dbp, flags) u_int32_t flags; { int ret; + u_int32_t bytes; dbp->locker = NULL; dbp->alt_close = NULL; @@ -254,6 +262,9 @@ __db_init(dbp, flags) dbp->get_alloc = __db_get_alloc; dbp->get_append_recno = __db_get_append_recno; dbp->get_assoc_flags = __db_get_assoc_flags; + dbp->get_blob_dir = __db_get_blob_dir; + dbp->get_blob_sub_dir = __db_get_blob_sub_dir; + dbp->get_blob_threshold = __db_get_blob_threshold; dbp->get_byteswapped = __db_get_byteswapped; dbp->get_cachesize = __db_get_cachesize; dbp->get_create_dir = __db_get_create_dir; @@ -290,6 +301,8 @@ __db_init(dbp, flags) dbp->rename = __db_rename_pp; dbp->set_alloc = __db_set_alloc; dbp->set_append_recno = __db_set_append_recno; + dbp->set_blob_dir = __db_set_blob_dir; + dbp->set_blob_threshold = __db_set_blob_threshold; dbp->set_cachesize = __db_set_cachesize; dbp->set_create_dir = __db_set_create_dir; dbp->set_dup_compare = __db_set_dup_compare; @@ -316,7 +329,11 @@ __db_init(dbp, flags) dbp->verify = __db_verify_pp; /* DB PUBLIC HANDLE LIST END */ - /* Access method specific. */ + if ((ret = __env_get_blob_threshold_int(dbp->env, &bytes)) != 0) + return (ret); + dbp->blob_threshold = bytes; + + /* Access method specific. */ if ((ret = __bam_db_create(dbp)) != 0) return (ret); if ((ret = __ham_db_create(dbp)) != 0) @@ -535,6 +552,182 @@ __db_set_append_recno(dbp, func) } /* + * __db_get_blob_threshold -- + * Get the current threshold size at which records are stored as blobs. + * + * PUBLIC: int __db_get_blob_threshold __P((DB *, u_int32_t *)); + */ +int +__db_get_blob_threshold(dbp, bytes) + DB *dbp; + u_int32_t *bytes; +{ + /* + * While shared, this value never changes after open, so it is safe + * to access it without mutex protection. + */ + *bytes = dbp->blob_threshold; + + return (0); +} + +/* + * __db_set_blob_threshold -- + * API to allow setting the threshold size at which records are stored + * as blobs rather than in database items. No flags currently supported. + * PUBLIC: int __db_set_blob_threshold __P((DB *, u_int32_t, u_int32_t)); + */ +int +__db_set_blob_threshold(dbp, bytes, flags) + DB *dbp; + u_int32_t bytes; + u_int32_t flags; +{ + if (__db_fchk(dbp->env, "DB->set_blob_threshold", flags, 0) != 0) + return (EINVAL); + + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_blob_threshold"); + + if (bytes != 0 && F_ISSET(dbp, + (DB_AM_CHKSUM | DB_AM_ENCRYPT | DB_AM_DUP | DB_AM_DUPSORT))) { + __db_errx(dbp->env, DB_STR("0760", +"Cannot enable blobs in databases with checksum, encryption, or duplicates.")); + return (EINVAL); + } +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp) && bytes != 0) { + __db_errx(dbp->env, DB_STR("0761", + "Cannot enable blobs in databases with compression.")); + return (EINVAL); + } +#endif + + dbp->blob_threshold = bytes; + + return (0); +} + +/* + * __db_blobs_enabled -- + * + * Used to tell if the database is configured to support blobs. + * PUBLIC: int __db_blobs_enabled __P((DB *)); + */ +int +__db_blobs_enabled(dbp) + DB *dbp; +{ + /* Blob threshold must be non-0. */ + if (!dbp->blob_threshold) + return (0); + /* Blobs cannot support encryption or checksum, but that may change. */ + if (F_ISSET(dbp, (DB_AM_CHKSUM | DB_AM_ENCRYPT))) + return (0); + /* Blobs do not support compression, but that may change. */ +#ifdef HAVE_COMPRESSION + if (DB_IS_COMPRESSED(dbp)) + return (0); +#endif + if (dbp->env->dbenv != NULL && + F_ISSET(dbp->env->dbenv, DB_ENV_TXN_SNAPSHOT)) + return (0); + /* Cannot support blobs in recno or queue. */ + if (dbp->type == DB_RECNO || dbp->type == DB_QUEUE) + return (0); + /* + * Cannot support dups because that would require comparing + * blob data items. + */ + if (F_ISSET(dbp, (DB_AM_DUP | DB_AM_DUPSORT))) + return (0); + /* No place to put blob files when using an in-memory db. */ + if (F_ISSET(dbp, (DB_AM_INMEM))) + return (0); + + /* BDB managed databases should not support blobs. */ + if ((dbp->fname != NULL && IS_DB_FILE(dbp->fname)) || + (dbp->dname != NULL && IS_DB_FILE(dbp->dname))) + return (0); + + return (1); +} + +/* + * __db_get_blob_sub_dir -- + * + * Returns the subdirectory of the blob directory in which the blob files + * for the given db are stored, or NULL if there is none. + * + */ +static int +__db_get_blob_sub_dir(dbp, dir) + DB *dbp; + const char **dir; +{ + DB_ILLEGAL_BEFORE_OPEN(dbp, "DB->get_blob_sub_dir"); + + *dir = dbp->blob_sub_dir; + + return (0); +} + +/* + * __db_get_blob_dir -- + * + * Get the blob directory for this database. + */ +static int +__db_get_blob_dir(dbp, dir) + DB *dbp; + const char **dir; +{ + DB_ENV *dbenv; + ENV *env; + + env = dbp->env; + dbenv = dbp->env->dbenv; + *dir = NULL; + + if (dbenv == NULL) + return (0); + + if (dbenv->db_blob_dir != NULL) + *dir = dbenv->db_blob_dir; + else if (env->db_home != NULL) + *dir = BLOB_DEFAULT_DIR; + + return (0); +} + +/* + * __db_set_blob_dir -- + * + * Set the blob directory in a local environment. + */ +static int +__db_set_blob_dir(dbp, dir) + DB *dbp; + const char *dir; +{ + DB_ENV *dbenv; + ENV *env; + + DB_ILLEGAL_IN_ENV(dbp, "DB->set_blob_dir"); + DB_ILLEGAL_AFTER_OPEN(dbp, "DB->set_blob_dir"); + env = dbp->env; + dbenv = dbp->env->dbenv; + + if (dbenv == NULL) + return (0); + + if (dbenv->db_blob_dir != NULL) + __os_free(env, dbenv->db_blob_dir); + dbenv->db_blob_dir = NULL; + + return (__os_strdup(env, dir, &dbenv->db_blob_dir)); +} + +/* * __db_get_cachesize -- * Get underlying cache size. */ @@ -607,7 +800,7 @@ __db_get_create_dir(dbp, dirp) static int __db_get_dup_compare(dbp, funcp) DB *dbp; - int (**funcp) __P((DB *, const DBT *, const DBT *)); + int (**funcp) __P((DB *, const DBT *, const DBT *, size_t *)); { DB_ILLEGAL_METHOD(dbp, DB_OK_BTREE | DB_OK_HASH); @@ -628,11 +821,14 @@ __db_get_dup_compare(dbp, funcp) /* * __db_set_dup_compare -- * Set duplicate comparison routine. + * + * PUBLIC: int __db_set_dup_compare __P((DB *, + * PUBLIC: int (*)(DB *, const DBT *, const DBT *, size_t *))); */ -static int +int __db_set_dup_compare(dbp, func) DB *dbp; - int (*func) __P((DB *, const DBT *, const DBT *)); + int (*func) __P((DB *, const DBT *, const DBT *, size_t *)); { int ret; @@ -900,6 +1096,13 @@ __db_set_flags(dbp, flags) ENV_REQUIRES_CONFIG(env, env->tx_handle, "DB_NOT_DURABLE", DB_INIT_TXN); + if (dbp->blob_threshold && + LF_ISSET(DB_CHKSUM | DB_ENCRYPT | DB_DUP | DB_DUPSORT)) { + __db_errx(dbp->env, DB_STR("0763", +"Cannot enable checksum, encryption, or duplicates with blob support.")); + return (EINVAL); + } + __db_map_flags(dbp, &flags, &dbp->flags); if ((ret = __bam_set_flags(dbp, &flags)) != 0) |