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

📄 hash.c

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 C
📖 第 1 页 / 共 4 页
字号:
				    nval->doff + nval->dlen, len);				p += len;			}			/* Final size. */			memcpy(p, &newsize, sizeof(db_indx_t));			/*			 * Make sure that the caller isn't corrupting			 * the sort order.			 */			if (dbp->dup_compare != NULL) {				tmp_val2.data =				    (u_int8_t *)newrec + sizeof(db_indx_t);				tmp_val2.size = newsize;				if (dbp->dup_compare(				    dbp, &tmp_val, &tmp_val2) != 0) {					(void)__os_free(dbenv, newrec);					return (__db_duperr(dbp, flags));				}			}			tmp_val2.data = newrec;			tmp_val2.size = DUP_SIZE(newsize);			tmp_val2.doff = hcp->dup_off;			tmp_val2.dlen = DUP_SIZE(hcp->dup_len);			ret = __ham_replpair(dbc, &tmp_val2, 0);			(void)__os_free(dbenv, newrec);			/* Update cursor */			if (ret != 0)				return (ret);			if (newsize > nondup_size)				hcp->dup_tlen += (newsize - nondup_size);			else				hcp->dup_tlen -= (nondup_size - newsize);			hcp->dup_len = DUP_SIZE(newsize);			return (0);		} else {			/* Check whether we need to convert to off page. */			if (ISBIG(hcp,			    hcp->dup_tlen - hcp->dup_len + nval->size)) {				if ((ret = __ham_dup_convert(dbc)) != 0)					return (ret);				return (hcp->opd->c_am_put(hcp->opd,				    NULL, nval, flags, NULL));			}			/* Make sure we maintain sort order. */			if (dbp->dup_compare != NULL) {				tmp_val2.data =				    HKEYDATA_DATA(H_PAIRDATA(dbp, hcp->page,				    hcp->indx)) + hcp->dup_off +				    sizeof(db_indx_t);				tmp_val2.size = hcp->dup_len;				if (dbp->dup_compare(dbp, nval, &tmp_val2) != 0)					return (EINVAL);			}			/* Overwriting a complete duplicate. */			if ((ret =			    __ham_make_dup(dbp->dbenv, nval, &tmp_val,			    &dbc->my_rdata.data, &dbc->my_rdata.ulen)) != 0)				return (ret);			/* Now fix what we are replacing. */			tmp_val.doff = hcp->dup_off;			tmp_val.dlen = DUP_SIZE(hcp->dup_len);			/* Update cursor */			if (nval->size > hcp->dup_len)				hcp->dup_tlen += (nval->size - hcp->dup_len);			else				hcp->dup_tlen -= (hcp->dup_len - nval->size);			hcp->dup_len = (db_indx_t)DUP_SIZE(nval->size);		}		myval = &tmp_val;	} else if (!F_ISSET(nval, DB_DBT_PARTIAL)) {		/* Put/overwrite */		memcpy(&tmp_val, nval, sizeof(*nval));		F_SET(&tmp_val, DB_DBT_PARTIAL);		tmp_val.doff = 0;		hk = H_PAIRDATA(dbp, hcp->page, hcp->indx);		if (HPAGE_PTYPE(hk) == H_OFFPAGE)			memcpy(&tmp_val.dlen,			    HOFFPAGE_TLEN(hk), sizeof(u_int32_t));		else			tmp_val.dlen = LEN_HDATA(dbp, hcp->page,			    hcp->hdr->dbmeta.pagesize, hcp->indx);		myval = &tmp_val;	} else		/* Regular partial put */		myval = nval;	return (__ham_replpair(dbc, myval, 0));}/* * Given a key and a cursor, sets the cursor to the page/ndx on which * the key resides.  If the key is found, the cursor H_OK flag is set * and the pagep, bndx, pgno (dpagep, dndx, dpgno) fields are set. * If the key is not found, the H_OK flag is not set.  If the sought * field is non-0, the pagep, bndx, pgno (dpagep, dndx, dpgno) fields * are set indicating where an add might take place.  If it is 0, * non of the cursor pointer field are valid. */static int__ham_lookup(dbc, key, sought, mode, pgnop)	DBC *dbc;	const DBT *key;	u_int32_t sought;	db_lockmode_t mode;	db_pgno_t *pgnop;{	DB *dbp;	HASH_CURSOR *hcp;	db_pgno_t pgno;	u_int32_t tlen;	int match, ret;	u_int8_t *hk, *dk;	dbp = dbc->dbp;	hcp = (HASH_CURSOR *)dbc->internal;	/*	 * Set up cursor so that we're looking for space to add an item	 * as we cycle through the pages looking for the key.	 */	if ((ret = __ham_item_reset(dbc)) != 0)		return (ret);	hcp->seek_size = sought;	hcp->bucket = __ham_call_hash(dbc, (u_int8_t *)key->data, key->size);	hcp->pgno = BUCKET_TO_PAGE(hcp, hcp->bucket);	for (;;) {		*pgnop = PGNO_INVALID;		if ((ret = __ham_item_next(dbc, mode, pgnop)) != 0)			return (ret);		if (F_ISSET(hcp, H_NOMORE))			break;		hk = H_PAIRKEY(dbp, hcp->page, hcp->indx);		switch (HPAGE_PTYPE(hk)) {		case H_OFFPAGE:			memcpy(&tlen, HOFFPAGE_TLEN(hk), sizeof(u_int32_t));			if (tlen == key->size) {				memcpy(&pgno,				    HOFFPAGE_PGNO(hk), sizeof(db_pgno_t));				if ((ret = __db_moff(dbp,				    key, pgno, tlen, NULL, &match)) != 0)					return (ret);				if (match == 0)					goto found_key;			}			break;		case H_KEYDATA:			if (key->size ==			    LEN_HKEY(dbp, hcp->page, dbp->pgsize, hcp->indx) &&			    memcmp(key->data,			    HKEYDATA_DATA(hk), key->size) == 0) {				/* Found the key, check for data type. */found_key:			F_SET(hcp, H_OK);				dk = H_PAIRDATA(dbp, hcp->page, hcp->indx);				if (HPAGE_PTYPE(dk) == H_OFFDUP)					memcpy(pgnop, HOFFDUP_PGNO(dk),					    sizeof(db_pgno_t));				return (0);			}			break;		case H_DUPLICATE:		case H_OFFDUP:			/*			 * These are errors because keys are never			 * duplicated, only data items are.			 */			return (__db_pgfmt(dbp->dbenv, PGNO(hcp->page)));		}	}	/*	 * Item was not found.	 */	if (sought != 0)		return (ret);	return (ret);}/* * __ham_init_dbt -- *	Initialize a dbt using some possibly already allocated storage *	for items. * * PUBLIC: int __ham_init_dbt __P((DB_ENV *, * PUBLIC:     DBT *, u_int32_t, void **, u_int32_t *)); */int__ham_init_dbt(dbenv, dbt, size, bufp, sizep)	DB_ENV *dbenv;	DBT *dbt;	u_int32_t size;	void **bufp;	u_int32_t *sizep;{	int ret;	memset(dbt, 0, sizeof(*dbt));	if (*sizep < size) {		if ((ret = __os_realloc(dbenv, size, bufp)) != 0) {			*sizep = 0;			return (ret);		}		*sizep = size;	}	dbt->data = *bufp;	dbt->size = size;	return (0);}/* * Adjust the cursor after an insert or delete.  The cursor passed is * the one that was operated upon; we just need to check any of the * others. * * len indicates the length of the item added/deleted * add indicates if the item indicated by the cursor has just been * added (add == 1) or deleted (add == 0). * dup indicates if the addition occurred into a duplicate set. * * PUBLIC: int __ham_c_update * PUBLIC:    __P((DBC *, u_int32_t, int, int)); */int__ham_c_update(dbc, len, add, is_dup)	DBC *dbc;	u_int32_t len;	int add, is_dup;{	DB *dbp, *ldbp;	DBC *cp;	DB_ENV *dbenv;	DB_LSN lsn;	DB_TXN *my_txn;	HASH_CURSOR *hcp, *lcp;	int found, ret;	u_int32_t order;	dbp = dbc->dbp;	dbenv = dbp->dbenv;	hcp = (HASH_CURSOR *)dbc->internal;	/*	 * Adjustment will only be logged if this is a subtransaction.	 * Only subtransactions can abort and effect their parent	 * transactions cursors.	 */	my_txn = IS_SUBTRANSACTION(dbc->txn) ? dbc->txn : NULL;	found = 0;	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	/*	 * Calculate the order of this deleted record.	 * This will be one greater than any cursor that is pointing	 * at this record and already marked as deleted.	 */	order = 0;	if (!add) {		order = 1;		for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);		    ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;		    ldbp = LIST_NEXT(ldbp, dblistlinks)) {			MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);			for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;			    cp = TAILQ_NEXT(cp, links)) {				if (cp == dbc || cp->dbtype != DB_HASH)					continue;				lcp = (HASH_CURSOR *)cp->internal;				if (F_ISSET(lcp, H_DELETED) &&				    hcp->pgno == lcp->pgno &&				    hcp->indx == lcp->indx &&				    order <= lcp->order &&				    (!is_dup || hcp->dup_off == lcp->dup_off))					order = lcp->order + 1;			}			MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);		}		hcp->order = order;	}	for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);	    ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;	    ldbp = LIST_NEXT(ldbp, dblistlinks)) {		MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);		for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;		    cp = TAILQ_NEXT(cp, links)) {			if (cp == dbc || cp->dbtype != DB_HASH)				continue;			lcp = (HASH_CURSOR *)cp->internal;			if (lcp->pgno != hcp->pgno || lcp->indx == NDX_INVALID)				continue;			if (my_txn != NULL && cp->txn != my_txn)				found = 1;			if (!is_dup) {				if (add) {					/*					 * This routine is not called to add					 * non-dup records which are always put					 * at the end.  It is only called from					 * recovery in this case and the					 * cursor will be marked deleted.					 * We are "undeleting" so unmark all					 * cursors with the same order.					 */					if (lcp->indx == hcp->indx &&					    F_ISSET(lcp, H_DELETED)) {						if (lcp->order == hcp->order)							F_CLR(lcp, H_DELETED);						else if (lcp->order >						    hcp->order) {						/*						 * If we've moved this cursor's						 * index, split its order						 * number--i.e., decrement it by						 * enough so that the lowest						 * cursor moved has order 1.						 * cp_arg->order is the split						 * point, so decrement by one						 * less than that.						 */							lcp->order -=							    (hcp->order - 1);							lcp->indx += 2;						}					} else if (lcp->indx >= hcp->indx)						lcp->indx += 2;				} else {					if (lcp->indx > hcp->indx) {						lcp->indx -= 2;						if (lcp->indx == hcp->indx &&						    F_ISSET(lcp, H_DELETED))							lcp->order += order;					} else if (lcp->indx == hcp->indx &&					    !F_ISSET(lcp, H_DELETED)) {						F_SET(lcp, H_DELETED);						F_CLR(lcp, H_ISDUP);						lcp->order = order;					}				}			} else if (lcp->indx == hcp->indx) {				/*				 * Handle duplicates.  This routine is				 * only called for on page dups.				 * Off page dups are handled by btree/rtree				 * code.				 */				if (add) {					lcp->dup_tlen += len;					if (lcp->dup_off == hcp->dup_off &&					    F_ISSET(hcp, H_DELETED) &&					    F_ISSET(lcp, H_DELETED)) {						/* Abort of a delete. */						if (lcp->order == hcp->order)							F_CLR(lcp, H_DELETED);						else if (lcp->order >						    hcp->order) {							lcp->order -=							    (hcp->order -1);							lcp->dup_off += len;						}					} else if (lcp->dup_off >= hcp->dup_off)						lcp->dup_off += len;				} else {					lcp->dup_tlen -= len;					if (lcp->dup_off > hcp->dup_off) {						lcp->dup_off -= len;						if (lcp->dup_off ==						    hcp->dup_off &&						    F_ISSET(lcp, H_DELETED))							lcp->order += order;					} else if (lcp->dup_off ==					    hcp->dup_off &&					    !F_ISSET(lcp, H_DELETED)) {						F_SET(lcp, H_DELETED);						lcp->order = order;					}				}			}		}		MUTEX_THREAD_UNLOCK(dbenv, dbp->mutexp);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	if (found != 0 && DBC_LOGGING(dbc)) {		if ((ret = __ham_curadj_log(dbp, my_txn, &lsn, 0, hcp->pgno,		    hcp->indx, len, hcp->dup_off, add, is_dup, order)) != 0)			return (ret);	}	return (0);}/* * __ham_get_clist -- * * Get a list of cursors either on a particular bucket or on a particular * page and index combination.  The former is so that we can update * cursors on a split.  The latter is so we can update cursors when we * move items off page. * * PUBLIC: int __ham_get_clist __P((DB *, db_pgno_t, u_int32_t, DBC ***)); */int__ham_get_clist(dbp, pgno, indx, listp)	DB *dbp;	db_pgno_t pgno;	u_int32_t indx;	DBC ***listp;{	DB *ldbp;	DBC *cp;	DB_ENV *dbenv;	int nalloc, nused, ret;	/*	 * Assume that finding anything is the exception, so optimize for	 * the case where there aren't any.	 */	nalloc = nused = 0;	*listp = NULL;	dbenv = dbp->dbenv;	MUTEX_THREAD_LOCK(dbenv, dbenv->dblist_mutexp);	for (ldbp = __dblist_get(dbenv, dbp->adj_fileid);	    ldbp != NULL && ldbp->adj_fileid == dbp->adj_fileid;	    ldbp = LIST_NEXT(ldbp, dblistlinks)) {		MUTEX_THREAD_LOCK(dbenv, dbp->mutexp);		for (cp = TAILQ_FIRST(&ldbp->active_queue); cp != NULL;		    cp = TAILQ_NEXT(cp, links))			/*			 * We match if cp->pgno matches the specified			 * pgno, and if either the cp->indx matches			 * or we weren't given an index.			 */			if (cp->internal->pgno == pgno &&			    (indx == NDX_INVALID ||			    cp->internal->indx == indx)) {				if (nused >= nalloc) {					nalloc += 10;					if ((ret = __os_realloc(dbp->dbenv,					    nalloc * sizeof(HASH_CURSOR *),					    listp)) != 0)						goto err;				}				(*listp)[nused++] = cp;			}		MUTEX_THREAD_UNLOCK(dbp->dbenv, dbp->mutexp);	}	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	if (listp != NULL) {		if (nused >= nalloc) {			nalloc++;			if ((ret = __os_realloc(dbp->dbenv,			    nalloc * sizeof(HASH_CURSOR *), listp)) != 0)				return (ret);		}		(*listp)[nused] = NULL;	}	return (0);err:	MUTEX_THREAD_UNLOCK(dbp->dbenv, dbp->mutexp);	MUTEX_THREAD_UNLOCK(dbenv, dbenv->dblist_mutexp);	return (ret);}static int__ham_c_writelock(dbc)	DBC *dbc;{	DB_ENV *dbenv;	DB_LOCK tmp_lock;	HASH_CURSOR *hcp;	int ret;	/*	 * All we need do is acquire the lock and let the off-page	 * dup tree do its thing.	 */	if (!STD_LOCKING(dbc))		return (0);	hcp = (HASH_CURSOR *)dbc->internal;	if ((!LOCK_ISSET(hcp->lock) || hcp->lock_mode == DB_LOCK_READ)) {		tmp_lock = hcp->lock;		if ((ret = __ham_lock_bucket(dbc, DB_LOCK_WRITE)) != 0)			return (ret);		dbenv = dbc->dbp->dbenv;		if (LOCK_ISSET(tmp_lock) &&		    (ret = dbenv->lock_put(dbenv, &tmp_lock)) != 0)			return (ret);	}	return (0);}

⌨️ 快捷键说明

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