aboutsummaryrefslogtreecommitdiff
path: root/db2/hash
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2000-01-02 06:01:06 +0000
committerUlrich Drepper <drepper@redhat.com>2000-01-02 06:01:06 +0000
commit8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3 (patch)
tree099a250d7366aef2ab028fdb24f0d692cd784b4a /db2/hash
parent9a6450d578556c11e7c173d2f28362345b8f1258 (diff)
downloadglibc-8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3.tar.xz
glibc-8d6f1731fcd082e4f744ba9cb4bde4be7c08f1b3.zip
Update.
* Makeconfig (all-subdirs): Remove db and db2. * db/*: Removed. * db2/*: Removed.
Diffstat (limited to 'db2/hash')
-rw-r--r--db2/hash/hash.c1337
-rw-r--r--db2/hash/hash.src231
-rw-r--r--db2/hash/hash_auto.c1554
-rw-r--r--db2/hash/hash_conv.c109
-rw-r--r--db2/hash/hash_dup.c656
-rw-r--r--db2/hash/hash_func.c219
-rw-r--r--db2/hash/hash_page.c1929
-rw-r--r--db2/hash/hash_rec.c986
-rw-r--r--db2/hash/hash_stat.c44
9 files changed, 0 insertions, 7065 deletions
diff --git a/db2/hash/hash.c b/db2/hash/hash.c
deleted file mode 100644
index 0d202fce20..0000000000
--- a/db2/hash/hash.c
+++ /dev/null
@@ -1,1337 +0,0 @@
-/*-
- * See the file LICENSE for redistribution information.
- *
- * Copyright (c) 1996, 1997, 1998
- * Sleepycat Software. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * Margo Seltzer. All rights reserved.
- */
-/*
- * Copyright (c) 1990, 1993, 1994
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * Margo Seltzer.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include "config.h"
-
-#ifndef lint
-static const char sccsid[] = "@(#)hash.c 10.63 (Sleepycat) 12/11/98";
-#endif /* not lint */
-
-#ifndef NO_SYSTEM_INCLUDES
-#include <sys/types.h>
-
-#include <errno.h>
-#include <stdlib.h>
-#include <string.h>
-#endif
-
-#include "db_int.h"
-#include "shqueue.h"
-#include "db_page.h"
-#include "db_am.h"
-#include "db_ext.h"
-#include "hash.h"
-#include "btree.h"
-#include "log.h"
-#include "db_shash.h"
-#include "lock.h"
-#include "lock_ext.h"
-
-static int __ham_c_close __P((DBC *));
-static int __ham_c_del __P((DBC *, u_int32_t));
-static int __ham_c_destroy __P((DBC *));
-static int __ham_c_get __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __ham_c_put __P((DBC *, DBT *, DBT *, u_int32_t));
-static int __ham_delete __P((DB *, DB_TXN *, DBT *, u_int32_t));
-static int __ham_dup_return __P((DBC *, DBT *, u_int32_t));
-static int __ham_expand_table __P((DBC *));
-static void __ham_init_htab __P((DBC *, u_int32_t, u_int32_t));
-static int __ham_lookup __P((DBC *, const DBT *, u_int32_t, db_lockmode_t));
-static int __ham_overwrite __P((DBC *, DBT *));
-
-/************************** INTERFACE ROUTINES ***************************/
-/* OPEN/CLOSE */
-
-/*
- * __ham_open --
- *
- * PUBLIC: int __ham_open __P((DB *, DB_INFO *));
- */
-int
-__ham_open(dbp, dbinfo)
- DB *dbp;
- DB_INFO *dbinfo;
-{
- DB_ENV *dbenv;
- DBC *dbc;
- HASH_CURSOR *hcp;
- int file_existed, ret;
-
- dbc = NULL;
- dbenv = dbp->dbenv;
-
- /* Set the hash function if specified by the user. */
- if (dbinfo != NULL && dbinfo->h_hash != NULL)
- dbp->h_hash = dbinfo->h_hash;
-
- /*
- * Initialize the remaining fields of the dbp. The only function
- * that differs from the default set is __ham_stat().
- */
- dbp->internal = NULL;
- dbp->am_close = __ham_close;
- dbp->del = __ham_delete;
- dbp->stat = __ham_stat;
-
- /* Get a cursor we can use for the rest of this function. */
- if ((ret = dbp->cursor(dbp, NULL, &dbc, 0)) != 0)
- goto out;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- goto out;
-
- /*
- * If this is a new file, initialize it, and put it back dirty.
- */
-
- /* Initialize the hdr structure */
- if (hcp->hdr->magic == DB_HASHMAGIC) {
- file_existed = 1;
- /* File exists, verify the data in the header. */
- if (dbp->h_hash == NULL)
- dbp->h_hash =
- hcp->hdr->version < 5 ? __ham_func4 : __ham_func5;
- if (dbp->h_hash(CHARKEY, sizeof(CHARKEY)) !=
- hcp->hdr->h_charkey) {
- __db_err(dbp->dbenv, "hash: incompatible hash function");
- ret = EINVAL;
- goto out;
- }
- if (F_ISSET(hcp->hdr, DB_HASH_DUP))
- F_SET(dbp, DB_AM_DUP);
- } else {
- /*
- * File does not exist, we must initialize the header. If
- * locking is enabled that means getting a write lock first.
- */
- file_existed = 0;
- if (F_ISSET(dbp, DB_AM_LOCKING) &&
- ((ret = lock_put(dbenv->lk_info, hcp->hlock)) != 0 ||
- (ret = lock_get(dbenv->lk_info, dbc->locker, 0,
- &dbc->lock_dbt, DB_LOCK_WRITE, &hcp->hlock)) != 0)) {
- if (ret < 0)
- ret = EAGAIN;
- goto out;
- }
-
- __ham_init_htab(dbc, dbinfo != NULL ? dbinfo->h_nelem : 0,
- dbinfo != NULL ? dbinfo->h_ffactor : 0);
- if (F_ISSET(dbp, DB_AM_DUP))
- F_SET(hcp->hdr, DB_HASH_DUP);
- if ((ret = __ham_dirty_page(dbp, (PAGE *)hcp->hdr)) != 0)
- goto out;
- }
-
- /* Release the meta data page */
- RELEASE_META(dbp, hcp);
- if ((ret = dbc->c_close(dbc)) != 0)
- goto out;
-
- /* Sync the file so that we know that the meta data goes to disk. */
- if (!file_existed && (ret = dbp->sync(dbp, 0)) != 0)
- goto out;
- return (0);
-
-out: (void)__ham_close(dbp);
- return (ret);
-}
-
-/*
- * PUBLIC: int __ham_close __P((DB *));
- */
-int
-__ham_close(dbp)
- DB *dbp;
-{
- COMPQUIET(dbp, NULL);
- return (0);
-}
-
-/************************** LOCAL CREATION ROUTINES **********************/
-/*
- * Returns 0 on No Error
- */
-static void
-__ham_init_htab(dbc, nelem, ffactor)
- DBC *dbc;
- u_int32_t nelem, ffactor;
-{
- DB *dbp;
- HASH_CURSOR *hcp;
- int32_t l2, nbuckets;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- dbp = dbc->dbp;
- memset(hcp->hdr, 0, sizeof(HASHHDR));
- hcp->hdr->ffactor = ffactor;
- hcp->hdr->pagesize = dbp->pgsize;
- ZERO_LSN(hcp->hdr->lsn);
- hcp->hdr->magic = DB_HASHMAGIC;
- hcp->hdr->version = DB_HASHVERSION;
-
- if (dbp->h_hash == NULL)
- dbp->h_hash = hcp->hdr->version < 5 ? __ham_func4 : __ham_func5;
- hcp->hdr->h_charkey = dbp->h_hash(CHARKEY, sizeof(CHARKEY));
- if (nelem != 0 && hcp->hdr->ffactor != 0) {
- nelem = (nelem - 1) / hcp->hdr->ffactor + 1;
- l2 = __db_log2(nelem > 2 ? nelem : 2);
- } else
- l2 = 2;
-
- nbuckets = 1 << l2;
-
- hcp->hdr->ovfl_point = l2;
- hcp->hdr->last_freed = PGNO_INVALID;
-
- hcp->hdr->max_bucket = hcp->hdr->high_mask = nbuckets - 1;
- hcp->hdr->low_mask = (nbuckets >> 1) - 1;
- memcpy(hcp->hdr->uid, dbp->fileid, DB_FILE_ID_LEN);
-}
-
-static int
-__ham_delete(dbp, txn, key, flags)
- DB *dbp;
- DB_TXN *txn;
- DBT *key;
- u_int32_t flags;
-{
- DBC *dbc;
- HASH_CURSOR *hcp;
- int ret, tret;
-
- DB_PANIC_CHECK(dbp);
-
- if ((ret =
- __db_delchk(dbp, key, flags, F_ISSET(dbp, DB_AM_RDONLY))) != 0)
- return (ret);
-
- if ((ret = dbp->cursor(dbp, txn, &dbc, DB_WRITELOCK)) != 0)
- return (ret);
-
- DEBUG_LWRITE(dbc, txn, "ham_delete", key, NULL, flags);
-
- hcp = (HASH_CURSOR *)dbc->internal;
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- goto out;
-
- hcp->stats.hash_deleted++;
- if ((ret = __ham_lookup(dbc, key, 0, DB_LOCK_WRITE)) == 0) {
- if (F_ISSET(hcp, H_OK))
- ret = __ham_del_pair(dbc, 1);
- else
- ret = DB_NOTFOUND;
- }
-
- RELEASE_META(dbp, hcp);
-out: if ((tret = dbc->c_close(dbc)) != 0 && ret == 0)
- ret = tret;
- return (ret);
-}
-
-/* ****************** CURSORS ********************************** */
-/*
- * __ham_c_init --
- * Initialize the hash-specific portion of a cursor.
- *
- * PUBLIC: int __ham_c_init __P((DBC *));
- */
-int
-__ham_c_init(dbc)
- DBC *dbc;
- {
- HASH_CURSOR *new_curs;
- int ret;
-
- if ((ret = __os_calloc(1, sizeof(struct cursor_t), &new_curs)) != 0)
- return (ret);
- if ((ret =
- __os_malloc(dbc->dbp->pgsize, NULL, &new_curs->split_buf)) != 0) {
- __os_free(new_curs, sizeof(*new_curs));
- return (ret);
- }
-
- new_curs->dbc = dbc;
-
- dbc->internal = new_curs;
- dbc->c_am_close = __ham_c_close;
- dbc->c_am_destroy = __ham_c_destroy;
- dbc->c_del = __ham_c_del;
- dbc->c_get = __ham_c_get;
- dbc->c_put = __ham_c_put;
-
- __ham_item_init(new_curs);
-
- return (0);
-}
-
-/*
- * __ham_c_close --
- * Close down the cursor from a single use.
- */
-static int
-__ham_c_close(dbc)
- DBC *dbc;
-{
- int ret;
-
- if ((ret = __ham_item_done(dbc, 0)) != 0)
- return (ret);
-
- __ham_item_init((HASH_CURSOR *)dbc->internal);
- return (0);
-}
-
-/*
- * __ham_c_destroy --
- * Cleanup the access method private part of a cursor.
- */
-static int
-__ham_c_destroy(dbc)
- DBC *dbc;
-{
- HASH_CURSOR *hcp;
-
- hcp = (HASH_CURSOR *)dbc->internal;
- if (hcp->split_buf != NULL)
- __os_free(hcp->split_buf, dbc->dbp->pgsize);
- __os_free(hcp, sizeof(HASH_CURSOR));
-
- return (0);
-}
-
-static int
-__ham_c_del(dbc, flags)
- DBC *dbc;
- u_int32_t flags;
-{
- DB *dbp;
- DBT repldbt;
- HASH_CURSOR *hcp;
- HASH_CURSOR save_curs;
- db_pgno_t ppgno, chg_pgno;
- int ret, t_ret;
-
- DEBUG_LWRITE(dbc, dbc->txn, "ham_c_del", NULL, NULL, flags);
- dbp = dbc->dbp;
- DB_PANIC_CHECK(dbp);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- if ((ret = __db_cdelchk(dbc->dbp, flags,
- F_ISSET(dbc->dbp, DB_AM_RDONLY), IS_VALID(hcp))) != 0)
- return (ret);
-
- if (F_ISSET(hcp, H_DELETED))
- return (DB_NOTFOUND);
-
- /*
- * If we are in the concurrent DB product and this cursor
- * is not a write cursor, then this request is invalid.
- * If it is a simple write cursor, then we need to upgrade its
- * lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- /* Make sure it's a valid update cursor. */
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
-
- SAVE_CURSOR(hcp, &save_curs);
- hcp->stats.hash_deleted++;
-
- if ((ret = __ham_get_cpage(dbc, DB_LOCK_WRITE)) != 0)
- goto out;
- if (F_ISSET(hcp, H_ISDUP) && hcp->dpgno != PGNO_INVALID) {
- /*
- * We are about to remove a duplicate from offpage.
- *
- * There are 4 cases.
- * 1. We will remove an item on a page, but there are more
- * items on that page.
- * 2. We will remove the last item on a page, but there is a
- * following page of duplicates.
- * 3. We will remove the last item on a page, this page was the
- * last page in a duplicate set, but there were dups before
- * it.
- * 4. We will remove the last item on a page, removing the last
- * duplicate.
- * In case 1 hcp->dpagep is unchanged.
- * In case 2 hcp->dpagep comes back pointing to the next dup
- * page.
- * In case 3 hcp->dpagep comes back NULL.
- * In case 4 hcp->dpagep comes back NULL.
- *
- * Case 4 results in deleting the pair off the master page.
- * The normal code for doing this knows how to delete the
- * duplicates, so we will handle this case in the normal code.
- */
- ppgno = PREV_PGNO(hcp->dpagep);
- if (ppgno == PGNO_INVALID &&
- NEXT_PGNO(hcp->dpagep) == PGNO_INVALID &&
- NUM_ENT(hcp->dpagep) == 1)
- goto normal;
-
- /* Remove item from duplicate page. */
- chg_pgno = hcp->dpgno;
- if ((ret = __db_drem(dbc,
- &hcp->dpagep, hcp->dndx, __ham_del_page)) != 0)
- goto out;
-
- if (hcp->dpagep == NULL) {
- if (ppgno != PGNO_INVALID) { /* Case 3 */
- hcp->dpgno = ppgno;
- if ((ret = __ham_get_cpage(dbc,
- DB_LOCK_READ)) != 0)
- goto out;
- hcp->dndx = NUM_ENT(hcp->dpagep);
- F_SET(hcp, H_DELETED);
- } else { /* Case 4 */
- ret = __ham_del_pair(dbc, 1);
- hcp->dpgno = PGNO_INVALID;
- /*
- * Delpair updated the cursor queue, so we
- * don't have to do that here.
- */
- chg_pgno = PGNO_INVALID;
- }
- } else if (PGNO(hcp->dpagep) != hcp->dpgno) {
- hcp->dndx = 0; /* Case 2 */
- hcp->dpgno = PGNO(hcp->dpagep);
- if (ppgno == PGNO_INVALID)
- memcpy(HOFFDUP_PGNO(P_ENTRY(hcp->pagep,
- H_DATAINDEX(hcp->bndx))),
- &hcp->dpgno, sizeof(db_pgno_t));
- /*
- * We need to put the master page here, because
- * although we have a duplicate page, the master
- * page is dirty, and ham_item_done assumes that
- * if you have a duplicate page, it's the only one
- * that can be dirty.
- */
- ret = __ham_put_page(dbp, hcp->pagep, 1);
- hcp->pagep = NULL;
- F_SET(hcp, H_DELETED);
- } else /* Case 1 */
- F_SET(hcp, H_DELETED);
- if (chg_pgno != PGNO_INVALID)
- __ham_c_update(hcp, chg_pgno, 0, 0, 1);
- } else if (F_ISSET(hcp, H_ISDUP)) { /* on page */
- if (hcp->dup_off == 0 && DUP_SIZE(hcp->dup_len) ==
- LEN_HDATA(hcp->pagep, hcp->hdr->pagesize, hcp->bndx))
- ret = __ham_del_pair(dbc, 1);
- else {
- repldbt.flags = 0;
- F_SET(&repldbt, DB_DBT_PARTIAL);
- repldbt.doff = hcp->dup_off;
- repldbt.dlen = DUP_SIZE(hcp->dup_len);
- repldbt.size = 0;
- repldbt.data =
- HKEYDATA_DATA(H_PAIRDATA(hcp->pagep, hcp->bndx));
- ret = __ham_replpair(dbc, &repldbt, 0);
- hcp->dup_tlen -= DUP_SIZE(hcp->dup_len);
- F_SET(hcp, H_DELETED);
- __ham_c_update(hcp, hcp->pgno,
- DUP_SIZE(hcp->dup_len), 0, 1);
- }
-
- } else
- /* Not a duplicate */
-normal: ret = __ham_del_pair(dbc, 1);
-
-out: if ((t_ret = __ham_item_done(dbc, ret == 0)) != 0 && ret == 0)
- ret = t_ret;
- RELEASE_META(dbp, hcp);
- RESTORE_CURSOR(dbp, hcp, &save_curs, ret);
- if (F_ISSET(dbp, DB_AM_CDB) && F_ISSET(dbc, DBC_RMW))
- (void)__lock_downgrade(dbp->dbenv->lk_info, dbc->mylock,
- DB_LOCK_IWRITE, 0);
- return (ret);
-}
-
-static int
-__ham_c_get(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB *dbp;
- HASH_CURSOR *hcp, save_curs;
- db_lockmode_t lock_type;
- int get_key, ret, t_ret;
-
- DEBUG_LREAD(dbc, dbc->txn, "ham_c_get",
- flags == DB_SET || flags == DB_SET_RANGE ? key : NULL,
- NULL, flags);
-
- hcp = (HASH_CURSOR *)dbc->internal;
- dbp = dbc->dbp;
- DB_PANIC_CHECK(dbp);
- SAVE_CURSOR(hcp, &save_curs);
- if ((ret =
- __db_cgetchk(dbp, key, data, flags, IS_VALID(hcp))) != 0)
- return (ret);
-
- /* Clear OR'd in additional bits so we can check for flag equality. */
- if (LF_ISSET(DB_RMW)) {
- lock_type = DB_LOCK_WRITE;
- LF_CLR(DB_RMW);
- } else
- lock_type = DB_LOCK_READ;
-
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
- hcp->stats.hash_get++;
- hcp->seek_size = 0;
-
- ret = 0;
- get_key = 1;
- switch (flags) {
- case DB_PREV:
- if (hcp->bucket != BUCKET_INVALID) {
- ret = __ham_item_prev(dbc, lock_type);
- break;
- }
- /* FALLTHROUGH */
- case DB_LAST:
- ret = __ham_item_last(dbc, lock_type);
- break;
- case DB_FIRST:
- ret = __ham_item_first(dbc, lock_type);
- break;
- case DB_NEXT_DUP:
- if (hcp->bucket == BUCKET_INVALID)
- ret = EINVAL;
- else {
- F_SET(hcp, H_DUPONLY);
- ret = __ham_item_next(dbc, lock_type);
- }
- break;
- case DB_NEXT:
- if (hcp->bucket == BUCKET_INVALID)
- hcp->bucket = 0;
- ret = __ham_item_next(dbc, lock_type);
- break;
- case DB_SET:
- case DB_SET_RANGE:
- case DB_GET_BOTH:
- if (F_ISSET(dbc, DBC_CONTINUE)) {
- F_SET(hcp, H_DUPONLY);
- ret = __ham_item_next(dbc, lock_type);
- } else if (F_ISSET(dbc, DBC_KEYSET))
- ret = __ham_item(dbc, lock_type);
- else
- ret = __ham_lookup(dbc, key, 0, lock_type);
- get_key = 0;
- break;
- case DB_CURRENT:
- if (F_ISSET(hcp, H_DELETED)) {
- ret = DB_KEYEMPTY;
- goto out;
- }
-
- ret = __ham_item(dbc, lock_type);
- break;
- }
-
- /*
- * Must always enter this loop to do error handling and
- * check for big key/data pair.
- */
- while (1) {
- if (ret != 0 && ret != DB_NOTFOUND)
- goto out1;
- else if (F_ISSET(hcp, H_OK)) {
- /* Get the key. */
- if (get_key && (ret = __db_ret(dbp, hcp->pagep,
- H_KEYINDEX(hcp->bndx), key, &dbc->rkey.data,
- &dbc->rkey.size)) != 0)
- goto out1;
-
- ret = __ham_dup_return(dbc, data, flags);
- break;
- } else if (!F_ISSET(hcp, H_NOMORE)) {
- abort();
- break;
- }
-
- /*
- * Ran out of entries in a bucket; change buckets.
- */
- switch (flags) {
- case DB_LAST:
- case DB_PREV:
- ret = __ham_item_done(dbc, 0);
- if (hcp->bucket == 0) {
- ret = DB_NOTFOUND;
- goto out1;
- }
- hcp->bucket--;
- hcp->bndx = NDX_INVALID;
- if (ret == 0)
- ret = __ham_item_prev(dbc, lock_type);
- break;
- case DB_FIRST:
- case DB_NEXT:
- ret = __ham_item_done(dbc, 0);
- hcp->bndx = NDX_INVALID;
- hcp->bucket++;
- hcp->pgno = PGNO_INVALID;
- hcp->pagep = NULL;
- if (hcp->bucket > hcp->hdr->max_bucket) {
- ret = DB_NOTFOUND;
- goto out1;
- }
- if (ret == 0)
- ret = __ham_item_next(dbc, lock_type);
- break;
- case DB_GET_BOTH:
- case DB_NEXT_DUP:
- case DB_SET:
- case DB_SET_RANGE:
- /* Key not found. */
- ret = DB_NOTFOUND;
- goto out1;
- }
- }
-out1: if ((t_ret = __ham_item_done(dbc, 0)) != 0 && ret == 0)
- ret = t_ret;
-out: RELEASE_META(dbp, hcp);
- RESTORE_CURSOR(dbp, hcp, &save_curs, ret);
- return (ret);
-}
-
-static int
-__ham_c_put(dbc, key, data, flags)
- DBC *dbc;
- DBT *key;
- DBT *data;
- u_int32_t flags;
-{
- DB *dbp;
- DBT tmp_val, *myval;
- HASH_CURSOR *hcp, save_curs;
- u_int32_t nbytes;
- int ret, t_ret;
-
- dbp = dbc->dbp;
- DB_PANIC_CHECK(dbp);
- DEBUG_LWRITE(dbc, dbc->txn, "ham_c_put",
- flags == DB_KEYFIRST || flags == DB_KEYLAST ? key : NULL,
- data, flags);
- hcp = (HASH_CURSOR *)dbc->internal;
-
- if ((ret = __db_cputchk(dbp, key, data, flags,
- F_ISSET(dbp, DB_AM_RDONLY), IS_VALID(hcp))) != 0)
- return (ret);
-
- if (F_ISSET(hcp, H_DELETED) &&
- flags != DB_KEYFIRST && flags != DB_KEYLAST)
- return (DB_NOTFOUND);
-
- /*
- * If we are in the concurrent DB product and this cursor
- * is not a write cursor, then this request is invalid.
- * If it is a simple write cursor, then we need to upgrade its
- * lock.
- */
- if (F_ISSET(dbp, DB_AM_CDB)) {
- /* Make sure it's a valid update cursor. */
- if (!F_ISSET(dbc, DBC_RMW | DBC_WRITER))
- return (EINVAL);
-
- if (F_ISSET(dbc, DBC_RMW) &&
- (ret = lock_get(dbp->dbenv->lk_info, dbc->locker,
- DB_LOCK_UPGRADE, &dbc->lock_dbt, DB_LOCK_WRITE,
- &dbc->mylock)) != 0)
- return (EAGAIN);
- }
-
- GET_META(dbp, hcp, ret);
- if (ret != 0)
- return (ret);
-
- SAVE_CURSOR(hcp, &save_curs);
- hcp->stats.hash_put++;
-
- switch (flags) {