⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
			case DB_PREV_NODUP:				ret = mpf->put(mpf, hcp->page, 0);				hcp->page = NULL;				if (hcp->bucket == 0) {					ret = DB_NOTFOUND;					hcp->pgno = PGNO_INVALID;					goto err;				}				F_CLR(hcp, H_ISDUP);				hcp->bucket--;				hcp->indx = NDX_INVALID;				hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);				if (ret == 0)					ret = __ham_item_prev(dbc,					    lock_type, pgnop);				break;			case DB_FIRST:			case DB_NEXT:			case DB_NEXT_NODUP:				ret = mpf->put(mpf, hcp->page, 0);				hcp->page = NULL;				hcp->indx = NDX_INVALID;				hcp->bucket++;				F_CLR(hcp, H_ISDUP);				hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);				if (hcp->bucket > hcp->hdr->max_bucket) {					ret = DB_NOTFOUND;					hcp->pgno = PGNO_INVALID;					goto err;				}				if (ret == 0)					ret = __ham_item_next(dbc,					    lock_type, pgnop);				break;			case DB_GET_BOTH:			case DB_GET_BOTHC:			case DB_GET_BOTH_RANGE:			case DB_NEXT_DUP:			case DB_SET:			case DB_SET_RANGE:				/* Key not found. */				ret = DB_NOTFOUND;				goto err;			case DB_CURRENT:				/*				 * This should only happen if you are doing				 * deletes and reading with concurrent threads				 * and not doing proper locking.  We return				 * the same error code as we would if the				 * cursor were deleted.				 */				ret = DB_KEYEMPTY;				goto err;			default:				DB_ASSERT(0);		}	}	if (get_key == 0)		F_SET(key, DB_DBT_ISSET);err:	if ((t_ret = __ham_release_meta(dbc)) != 0 && ret == 0)		ret = t_ret;	F_CLR(hcp, H_DUPONLY);	F_CLR(hcp, H_NEXT_NODUP);	return (ret);}/* * __ham_bulk -- Return bulk data from a hash table. */static int__ham_bulk(dbc, data, flags)	DBC *dbc;	DBT *data;	u_int32_t flags;{	DB *dbp;	DB_MPOOLFILE *mpf;	HASH_CURSOR *cp;	PAGE *pg;	db_indx_t dup_len, dup_off, dup_tlen, indx, *inp;	db_lockmode_t lock_mode;	db_pgno_t pgno;	int32_t  *endp, key_off, *offp, *saveoff;	u_int32_t key_size, size, space;	u_int8_t *dbuf, *dp, *hk, *np, *tmp;	int is_dup, is_key;	int need_pg, next_key, no_dup, pagesize, ret, t_ret;	ret = 0;	key_off = 0;	dup_len = dup_off = dup_tlen = 0;	size = 0;	dbp = dbc->dbp;	pagesize = dbp->pgsize;	mpf = dbp->mpf;	cp = (HASH_CURSOR *)dbc->internal;	is_key = LF_ISSET(DB_MULTIPLE_KEY) ? 1 : 0;	next_key = is_key && LF_ISSET(DB_OPFLAGS_MASK) != DB_NEXT_DUP;	no_dup = LF_ISSET(DB_OPFLAGS_MASK) == DB_NEXT_NODUP;	dbuf = data->data;	np = dp = dbuf;	/* Keep track of space that is left.  There is an termination entry */	space = data->ulen;	space -= sizeof(*offp);	/* Build the offset/size table from the end up. */	endp = (int32_t *) ((u_int8_t *)dbuf + data->ulen);	endp--;	offp = endp;	key_size = 0;	lock_mode = F_ISSET(dbc, DBC_RMW) ? DB_LOCK_WRITE: DB_LOCK_READ;next_pg:	need_pg = 1;	indx = cp->indx;	pg = cp->page;	inp = P_INP(dbp, pg);	do {		if (is_key) {			hk = H_PAIRKEY(dbp, pg, indx);			if (HPAGE_PTYPE(hk) == H_OFFPAGE) {				memcpy(&key_size,				    HOFFPAGE_TLEN(hk), sizeof(u_int32_t));				memcpy(&pgno,				    HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));				size = key_size;				if (key_size > space)					goto get_key_space;				if ((ret = __bam_bulk_overflow(				    dbc, key_size, pgno, np)) != 0)					return (ret);				space -= key_size;				key_off = (int32_t)(np - dbuf);				np += key_size;			} else {				if (need_pg) {					dp = np;					size = pagesize - HOFFSET(pg);					if (space < size) {get_key_space:						if (offp == endp) {							data->size =							    ALIGN(size +							    pagesize,							    sizeof(u_int32_t));							return (ENOMEM);						}						goto back_up;					}					memcpy(dp,					   (u_int8_t *)pg + HOFFSET(pg), size);					need_pg = 0;					space -= size;					np += size;				}				key_size = LEN_HKEY(dbp, pg, pagesize, indx);				key_off = (int32_t)(inp[indx] - HOFFSET(pg)				    + dp - dbuf + SSZA(HKEYDATA, data));			}		}		hk = H_PAIRDATA(dbp, pg, indx);		switch (HPAGE_PTYPE(hk)) {		case H_DUPLICATE:		case H_KEYDATA:			if (need_pg) {				dp = np;				size = pagesize - HOFFSET(pg);				if (space < size) {back_up:					if (indx != 0) {						indx -= 2;						/* XXX						 * It's not clear that this is						 * the right way to fix this,						 * but here goes.						 * If we are backing up onto a						 * duplicate, then we need to						 * position ourselves at the						 * end of the duplicate set.						 * We probably need to make						 * this work for H_OFFDUP too.						 * It might be worth making a						 * dummy cursor and calling						 * __ham_item_prev.						 */						tmp = H_PAIRDATA(dbp, pg, indx);						if (HPAGE_PTYPE(tmp) ==						    H_DUPLICATE) {							dup_off = dup_tlen =							    LEN_HDATA(dbp, pg,							    pagesize, indx + 1);							memcpy(&dup_len,							    HKEYDATA_DATA(tmp),							    sizeof(db_indx_t));						}						goto get_space;					}					/* indx == 0 */					if ((ret = __ham_item_prev(dbc,					    lock_mode, &pgno)) != 0) {						if (ret != DB_NOTFOUND)							return (ret);						if ((ret = mpf->put(mpf,						    cp->page, 0)) != 0)							return (ret);						cp->page = NULL;						if (cp->bucket == 0) {							cp->indx = indx =							    NDX_INVALID;							goto get_space;						}						if ((ret =						    __ham_get_meta(dbc)) != 0)							return (ret);						cp->bucket--;						cp->pgno = BUCKET_TO_PAGE(cp,						    cp->bucket);						cp->indx = NDX_INVALID;						if ((ret = __ham_release_meta(						    dbc)) != 0)							return (ret);						if ((ret = __ham_item_prev(dbc,						    lock_mode, &pgno)) != 0)							return (ret);					}					indx = cp->indx;get_space:					/*					 * See if we put any data in the buffer.					 */					if (offp >= endp ||					    F_ISSET(dbc, DBC_TRANSIENT)) {						data->size = ALIGN(size +						    data->ulen - space,						    sizeof(u_int32_t));						return (ENOMEM);					}					/*					 * Don't continue;  we're all out					 * of space, even though we're					 * returning success.					 */					next_key = 0;					break;				}				memcpy(dp, (u_int8_t *)pg + HOFFSET(pg), size);				need_pg = 0;				space -= size;				np += size;			}			/*			 * We're about to crack the offset(s) and length(s)			 * out of an H_KEYDATA or H_DUPLICATE item.			 * There are three cases:			 *   1. We were moved into a duplicate set by			 *	the standard hash cursor code.  Respect			 *	the dup_off and dup_tlen we were given.			 *   2. We stumbled upon a duplicate set while			 *	walking the page on our own.  We need to			 *	recognize it as a dup and set dup_off and			 *	dup_tlen.			 *   3. The current item is not a dup.			 */			if (F_ISSET(cp, H_ISDUP)) {				/* Case 1 */				is_dup = 1;				dup_len = cp->dup_len;				dup_off = cp->dup_off;				dup_tlen = cp->dup_tlen;			} else if (HPAGE_PTYPE(hk) == H_DUPLICATE) {				/* Case 2 */				is_dup = 1;				/*				 * If we run out of memory and bail,				 * make sure the fact we're in a dup set				 * isn't ignored later.				 */				F_SET(cp, H_ISDUP);				dup_off = 0;				memcpy(&dup_len,				    HKEYDATA_DATA(hk), sizeof(db_indx_t));				dup_tlen = LEN_HDATA(dbp, pg, pagesize, indx);			} else				/* Case 3 */				is_dup = dup_len = dup_off = dup_tlen = 0;			do {				space -= (is_key ? 4 : 2) * sizeof(*offp);				size += (is_key ? 4 : 2) * sizeof(*offp);				/*				 * Since space is an unsigned, if we happen				 * to wrap, then this comparison will turn out				 * to be true.  XXX Wouldn't it be better to				 * simply check above that space is greater than				 * the value we're about to subtract???				 */				if (space > data->ulen) {					if (!is_dup || dup_off == 0)						goto back_up;					dup_off -= (db_indx_t)DUP_SIZE(offp[1]);					goto get_space;				}				if (is_key) {					*offp-- = key_off;					*offp-- = key_size;				}				if (is_dup) {					*offp-- = (int32_t)(					    inp[indx + 1] - HOFFSET(pg) +					    dp - dbuf + SSZA(HKEYDATA, data) +					    dup_off + sizeof(db_indx_t));					memcpy(&dup_len,					    HKEYDATA_DATA(hk) + dup_off,					    sizeof(db_indx_t));					dup_off += DUP_SIZE(dup_len);					*offp-- = dup_len;				} else {					*offp-- = (int32_t)(					    inp[indx + 1] - HOFFSET(pg) +					    dp - dbuf + SSZA(HKEYDATA, data));					*offp-- = LEN_HDATA(dbp, pg,					    pagesize, indx);				}			} while (is_dup && dup_off < dup_tlen && no_dup == 0);			F_CLR(cp, H_ISDUP);			break;		case H_OFFDUP:			memcpy(&pgno, HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));			space -= 2 * sizeof(*offp);			if (space > data->ulen)				goto back_up;			if (is_key) {				space -= 2 * sizeof(*offp);				if (space > data->ulen)					goto back_up;				*offp-- = key_off;				*offp-- = key_size;			}			saveoff = offp;			if ((ret = __bam_bulk_duplicates(dbc,			    pgno, dbuf, is_key ? offp + 2 : NULL,			    &offp, &np, &space, no_dup)) != 0) {				if (ret == ENOMEM) {					size = space;					if (is_key && saveoff == offp) {						offp += 2;						goto back_up;					}					goto get_space;				}				return (ret);			}			break;		case H_OFFPAGE:			space -= (is_key ? 4 : 2) * sizeof(*offp);			if (space > data->ulen)				goto back_up;			memcpy(&size, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));			memcpy(&pgno, HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));			if (size > space)				goto back_up;			if ((ret =			    __bam_bulk_overflow(dbc, size, pgno, np)) != 0)				return (ret);			if (is_key) {				*offp-- = key_off;				*offp-- = key_size;			}			*offp-- = (int32_t)(np - dbuf);			*offp-- = size;			np += size;			space -= size;			break;		}	} while (next_key && (indx += 2) < NUM_ENT(pg));	cp->indx = indx;	cp->dup_len = dup_len;	cp->dup_off = dup_off;	cp->dup_tlen = dup_tlen;	/* If we are off the page then try to the next page. */	if (ret == 0 && next_key && indx >= NUM_ENT(pg)) {		if ((ret = __ham_item_next(dbc, lock_mode, &pgno)) == 0)			goto next_pg;		if (ret != DB_NOTFOUND)			return (ret);		if ((ret = mpf->put(dbc->dbp->mpf, cp->page, 0)) != 0)			return (ret);		cp->page = NULL;		if ((ret = __ham_get_meta(dbc)) != 0)			return (ret);		cp->bucket++;		if (cp->bucket > cp->hdr->max_bucket) {			/*			 * Restore cursor to its previous state.  We're past			 * the last item in the last bucket, so the next			 * DBC->c_get(DB_NEXT) will return DB_NOTFOUND.			 */			cp->bucket--;			ret = DB_NOTFOUND;		} else {			/*			 * Start on the next bucket.			 *			 * Note that if this new bucket happens to be empty,			 * but there's another non-empty bucket after it,			 * we'll return early.  This is a rare case, and we			 * don't guarantee any particular number of keys			 * returned on each call, so just let the next call			 * to bulk get move forward by yet another bucket.			 */			cp->pgno = BUCKET_TO_PAGE(cp, cp->bucket);			cp->indx = NDX_INVALID;			F_CLR(cp, H_ISDUP);			ret = __ham_item_next(dbc, lock_mode, &pgno);		}		if ((t_ret = __ham_release_meta(dbc)) != 0)			return (t_ret);		if (ret == 0)			goto next_pg;		if (ret != DB_NOTFOUND)			return (ret);	}	*offp = (u_int32_t) -1;	return (0);}static int__ham_c_put(dbc, key, data, flags, pgnop)	DBC *dbc;	DBT *key;	DBT *data;	u_int32_t flags;	db_pgno_t *pgnop;{	DB *dbp;	DB_MPOOLFILE *mpf;	DBT tmp_val, *myval;	HASH_CURSOR *hcp;	u_int32_t nbytes;	int ret, t_ret;	/*	 * The compiler doesn't realize that we only use this when ret is	 * equal to 0 and that if ret is equal to 0, that we must have set	 * myval.  So, we initialize it here to shut the compiler up.	 */	COMPQUIET(myval, NULL);	dbp = dbc->dbp;	mpf = dbp->mpf;	hcp = (HASH_CURSOR *)dbc->internal;	if (F_ISSET(hcp, H_DELETED) &&	    flags != DB_KEYFIRST && flags != DB_KEYLAST)		return (DB_NOTFOUND);	if ((ret = __ham_get_meta(dbc)) != 0)		goto err1;	switch (flags) {	case DB_KEYLAST:	case DB_KEYFIRST:	case DB_NODUPDATA:		nbytes = (ISBIG(hcp, key->size) ? HOFFPAGE_PSIZE :		    HKEYDATA_PSIZE(key->size)) +		    (ISBIG(hcp, data->size) ? HOFFPAGE_PSIZE :		    HKEYDATA_PSIZE(data->size));		if ((ret = __ham_lookup(dbc,		    key, nbytes, DB_LOCK_WRITE, pgnop)) == DB_NOTFOUND) {			ret = 0;			if (hcp->seek_found_page != PGNO_INVALID &&			    hcp->seek_found_page != hcp->pgno) {				if ((ret = mpf->put(mpf, hcp->page, 0)) != 0)					goto err2;				hcp->page = NULL;				hcp->pgno = hcp->seek_found_page;				hcp->indx = NDX_INVALID;			}			if (F_ISSET(data, DB_DBT_PARTIAL) && data->doff != 0) {				/*				 * A partial put, but the key does not exist				 * and we are not beginning the write at 0.				 * We must create a data item padded up to doff				 * and then write the new bytes represented by				 * val.				 */				if ((ret = __ham_init_dbt(dbp->dbenv, &tmp_val,				    data->size + data->doff,				    &dbc->my_rdata.data,				    &dbc->my_rdata.ulen)) == 0) {					memset(tmp_val.data, 0, data->doff);					memcpy((u_int8_t *)tmp_val.data +					    data->doff, data->data, data->size);					myval = &tmp_val;				}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -