hashp->hdr->ffactor = dbinfo != NULL && dbinfo->h_ffactor ? dbinfo->h_ffactor : 0; __ham_init_htab(hashp, dbinfo != NULL ? dbinfo->h_nelem : 0);
__ham_init_htab(hashp, dbinfo != NULL ? dbinfo->h_nelem : 0, dbinfo != NULL ? dbinfo->h_ffactor : 0);
__ham_open(dbp, dbinfo)	DB *dbp;	DB_INFO *dbinfo;{	DB_ENV *dbenv;	DBC *curs;	HTAB *hashp;	int file_existed, ret;	dbenv = dbp->dbenv;	if ((hashp = (HTAB *)__db_calloc(1, sizeof(HTAB))) == NULL)		return (ENOMEM);	hashp->dbp = dbp;	/* Set the hash function if specified by the user. */	if (dbinfo != NULL && dbinfo->h_hash != NULL)		hashp->hash = dbinfo->h_hash;	/*	 * Initialize the remaining fields of the dbp.  The type, close and	 * fd functions are all set in db_open.	 */	dbp->internal = hashp;	dbp->cursor = __ham_cursor;	dbp->del = __ham_delete;	dbp->get = __ham_get;	dbp->put = __ham_put;	dbp->sync = __ham_sync;	/* If locking is turned on, lock the meta data page. */	if (F_ISSET(dbp, DB_AM_LOCKING)) {		dbp->lock.pgno = BUCKET_INVALID;		if ((ret = lock_get(dbenv->lk_info, dbp->locker,		    0, &dbp->lock_dbt, DB_LOCK_READ, &hashp->hlock)) != 0) {			if (ret < 0)				ret = EAGAIN;			goto out;		}	}	/*	 * Now, we can try to read the meta-data page and figure out	 * if we set up locking and get the meta-data page properly.	 * If this is a new file, initialize it, and put it back dirty.	 */	if ((ret = __ham_get_page(hashp->dbp, 0, (PAGE **)&hashp->hdr)) != 0)		goto out;	/* Initialize the hashp structure */	if (hashp->hdr->magic == DB_HASHMAGIC) {		file_existed = 1;		/* File exists, verify the data in the header. */		if (hashp->hash == NULL)			hashp->hash =			    hashp->hdr->version < 5 ? __ham_func4 : __ham_func5;		if (hashp->hash(CHARKEY, sizeof(CHARKEY)) !=		    hashp->hdr->h_charkey) {			__db_err(hashp->dbp->dbenv,			    "hash: incompatible hash function");			ret = EINVAL;			goto out;		}		if (F_ISSET(hashp->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, hashp->hlock)) != 0 ||		    (ret = lock_get(dbenv->lk_info, dbp->locker, 0,		        &dbp->lock_dbt, DB_LOCK_WRITE, &hashp->hlock)) != 0)) {			if (ret < 0)				ret = EAGAIN;			goto out;		}		hashp->hdr->ffactor =		    dbinfo != NULL && dbinfo->h_ffactor ? dbinfo->h_ffactor : 0;		__ham_init_htab(hashp, dbinfo != NULL ? dbinfo->h_nelem : 0);		if (F_ISSET(dbp, DB_AM_DUP))			F_SET(hashp->hdr, DB_HASH_DUP);		if ((ret = __ham_dirty_page(hashp, (PAGE *)hashp->hdr)) != 0)			goto out;	}	/* Initialize the default cursor. */	__ham_c_init(dbp, NULL, &curs);	TAILQ_INSERT_TAIL(&dbp->curs_queue, curs, links);	/* Allocate memory for our split buffer. */	if ((hashp->split_buf = (PAGE *)__db_malloc(dbp->pgsize)) == NULL) {		ret = ENOMEM;		goto out;	}#ifdef NO_STATISTICS_FOR_DB_ERR	__db_err(dbp->dbenv,	    "%s%lx\n%s%ld\n%s%ld\n%s%ld\n%s%ld\n%s0x%lx\n%s0x%lx\n%s%ld\n%s%ld\n%s0x%lx",	    "TABLE POINTER   ", (long)hashp,	    "BUCKET SIZE     ", (long)hashp->hdr->pagesize,	    "FILL FACTOR     ", (long)hashp->hdr->ffactor,	    "MAX BUCKET      ", (long)hashp->hdr->max_bucket,	    "OVFL POINT      ", (long)hashp->hdr->ovfl_point,	    "LAST FREED      ", (long)hashp->hdr->last_freed,	    "HIGH MASK       ", (long)hashp->hdr->high_mask,	    "LOW  MASK       ", (long)hashp->hdr->low_mask,	    "NELEM           ", (long)hashp->hdr->nelem,	    "FLAGS           ", (long)hashp->hdr->flags);#endif	/* Release the meta data page */	(void)__ham_put_page(hashp->dbp, (PAGE *)hashp->hdr, 0);	if (F_ISSET(dbp, DB_AM_LOCKING) &&	    (ret = lock_put(dbenv->lk_info, hashp->hlock)) != 0) {		if (ret < 0)			ret = EAGAIN;		goto out;	}	hashp->hlock = 0;	hashp->hdr = NULL;	/* 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);}