summaryrefslogtreecommitdiff
path: root/src/db/db_ret.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-02-17 17:25:57 +0000
committer <>2015-03-17 16:26:24 +0000
commit780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch)
tree598f8b9fa431b228d29897e798de4ac0c1d3d970 /src/db/db_ret.c
parent7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff)
downloadberkeleydb-master.tar.gz
Imported from /home/lorry/working-area/delta_berkeleydb/db-6.1.23.tar.gz.HEADdb-6.1.23master
Diffstat (limited to 'src/db/db_ret.c')
-rw-r--r--src/db/db_ret.c122
1 files changed, 121 insertions, 1 deletions
diff --git a/src/db/db_ret.c b/src/db/db_ret.c
index 709605f6..ddd0ef51 100644
--- a/src/db/db_ret.c
+++ b/src/db/db_ret.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -29,18 +29,27 @@ __db_ret(dbc, h, indx, dbt, memp, memsize)
void **memp;
u_int32_t *memsize;
{
+ BBLOB bl;
BKEYDATA *bk;
BOVERFLOW *bo;
DB *dbp;
+ ENV *env;
+ HBLOB hblob;
+ HEAPBLOBHDR bhdr;
HEAPHDR *hdr;
+ db_seq_t blob_id;
+ int ret;
HOFFPAGE ho;
+ off_t blob_size;
u_int32_t len;
u_int8_t *hk;
void *data;
if (F_ISSET(dbt, DB_DBT_READONLY))
return (0);
+ ret = 0;
dbp = dbc->dbp;
+ env = dbp->env;
switch (TYPE(h)) {
case P_HASH_UNSORTED:
@@ -50,6 +59,20 @@ __db_ret(dbc, h, indx, dbt, memp, memsize)
memcpy(&ho, hk, sizeof(HOFFPAGE));
return (__db_goff(dbc, dbt,
ho.tlen, ho.pgno, memp, memsize));
+ } else if (HPAGE_PTYPE(hk) == H_BLOB) {
+ /* Get the record instead of the blob item. */
+ if (F_ISSET(dbt, DB_DBT_BLOB_REC)) {
+ data = P_ENTRY(dbp, h, indx);
+ len = HBLOB_SIZE;
+ break;
+ }
+ memcpy(&hblob, hk, HBLOB_SIZE);
+ blob_id = (db_seq_t)hblob.id;
+ GET_BLOB_SIZE(env, hblob, blob_size, ret);
+ if (ret != 0)
+ return (ret);
+ return (__blob_get(
+ dbc, dbt, blob_id, blob_size, memp, memsize));
}
len = LEN_HKEYDATA(dbp, h, dbp->pgsize, indx);
data = HKEYDATA_DATA(hk);
@@ -58,6 +81,21 @@ __db_ret(dbc, h, indx, dbt, memp, memsize)
hdr = (HEAPHDR *)P_ENTRY(dbp, h, indx);
if (F_ISSET(hdr,(HEAP_RECSPLIT | HEAP_RECFIRST)))
return (__heapc_gsplit(dbc, dbt, memp, memsize));
+ else if (F_ISSET(hdr, HEAP_RECBLOB)) {
+ /* Get the record instead of the blob item. */
+ if (F_ISSET(dbt, DB_DBT_BLOB_REC)) {
+ data = P_ENTRY(dbp, h, indx);
+ len = HEAPBLOBREC_SIZE;
+ break;
+ }
+ memcpy(&bhdr, hdr, HEAPBLOBREC_SIZE);
+ blob_id = (db_seq_t)bhdr.id;
+ GET_BLOB_SIZE(env, bhdr, blob_size, ret);
+ if (ret != 0)
+ return (ret);
+ return (__blob_get(
+ dbc, dbt, blob_id, blob_size, memp, memsize));
+ }
len = hdr->size;
data = (u_int8_t *)hdr + sizeof(HEAPHDR);
break;
@@ -69,6 +107,20 @@ __db_ret(dbc, h, indx, dbt, memp, memsize)
bo = (BOVERFLOW *)bk;
return (__db_goff(dbc, dbt,
bo->tlen, bo->pgno, memp, memsize));
+ } else if (B_TYPE(bk->type) == B_BLOB) {
+ /* Get the record instead of the blob item. */
+ if (F_ISSET(dbt, DB_DBT_BLOB_REC)) {
+ data = P_ENTRY(dbp, h, indx);
+ len = BBLOB_SIZE;
+ break;
+ }
+ memcpy(&bl, bk, BBLOB_SIZE);
+ blob_id = (db_seq_t)bl.id;
+ GET_BLOB_SIZE(env, bl, blob_size, ret);
+ if (ret != 0)
+ return (ret);
+ return (__blob_get(
+ dbc, dbt, blob_id, blob_size, memp, memsize));
}
len = bk->len;
data = bk->data;
@@ -167,3 +219,71 @@ __db_retcopy(env, dbt, data, len, memp, memsize)
return (ret);
}
+
+/*
+ * __db_dbt_clone --
+ * Clone a DBT from another DBT.
+ * The input dest DBT must be a zero initialized DBT that will be populated.
+ * The function does not allocate a dest DBT to allow for cloning into stack
+ * or locally allocated variables. It is the callers responsibility to free
+ * the memory allocated in dest->data.
+ *
+ * PUBLIC: int __db_dbt_clone __P((ENV *, DBT *, const DBT *));
+ */
+int
+__db_dbt_clone(env, dest, src)
+ ENV *env;
+ DBT *dest;
+ const DBT *src;
+{
+ u_int32_t err_flags;
+ int ret;
+
+ DB_ASSERT(env, dest->data == NULL);
+
+ ret = 0;
+
+ /* The function does not support the following DBT flags. */
+ err_flags = DB_DBT_MALLOC | DB_DBT_REALLOC |
+ DB_DBT_MULTIPLE | DB_DBT_PARTIAL;
+ if (F_ISSET(src, err_flags)) {
+ __db_errx(env, DB_STR("0758",
+ "Unsupported flags when cloning the DBT."));
+ return (EINVAL);
+ }
+
+ if ((ret = __os_malloc(env, src->size, &dest->data)) != 0)
+ return (ret);
+
+ memcpy(dest->data, src->data, src->size);
+ dest->ulen = src->size;
+ dest->size = src->size;
+ dest->flags = DB_DBT_USERMEM;
+
+ return (ret);
+}
+
+/*
+ * __db_dbt_clone_free --
+ * Free a DBT cloned by __db_dbt_clone
+ *
+ * PUBLIC: int __db_dbt_clone_free __P((ENV *, DBT *));
+ */
+int
+__db_dbt_clone_free(env, dbt)
+ ENV *env;
+ DBT *dbt;
+{
+ /* Currently only DB_DBT_USERMEM is supported. */
+ if (dbt->flags != DB_DBT_USERMEM) {
+ __db_errx(env, DB_STR("0759",
+ "Unsupported flags when freeing the cloned DBT."));
+ return (EINVAL);
+ }
+
+ if (dbt->data != NULL)
+ __os_free(env, dbt->data);
+ dbt->size = dbt->ulen = 0;
+
+ return (0);
+}