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

📄 ridxio.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	nrec = 0;	while ( cur < end ) {		if ( (cur->type[0] == 0) && (cur->type[1] != 0) ) {			nrec++;		}		*(nxt++) = *cur;		memset(cur, 0, (size_t)sizeof(DfRecordIndex)); /* The old block is cleared to 0. */		cur++;	}	fmpSetRIdxMapFlag(ri, MD_WRITE);	fmpUnmapDisk(nxtmid, MD_WRITE);	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Adjust the indirect index. */	err = tuneIIdx(&curidx, &nxtidx, ofcb->idxlv, nrec, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	return nrec;err_ret:	DEBUG_PRINT(("divideRIdxBlock err = %d\n", err));	return err;}/* * Add the record index. *	Add the new record index just after the current location of ri. *	The added record index is cleared to 0 *	The current location of ri does not change. */LOCAL ER appendRIdx( RIdx *ri, RCB *rcb ){	DfRecordIndex	*ridx;	W		cur, top, end, i;	W		nrec, arec;	ER		err;	cur = (ri->mapadr - ri->mapbase) - 1;	top = (W)TopRIdx(ri->ofcb->idxlv, ri->ofcb);	end = (W)(ri->ofcb->fsinfo->sblk / sizeof(DfRecordIndex));	arec = 0;  /* The record count after the current record */	/* Find an unused index from after the current record index. */	for ( i = cur + 1; i < end; ++i ) {		ridx = &ri->mapbase[i];		if ( (ridx->type[0] == 0) && (ridx->type[1] == 0) ) {			/* Move index to make a space just after cur. */			nrec = shiftDownRIdx(ri->mapbase, cur + 1, i);			fmpSetRIdxMapFlag(ri, MD_WRITE);			/* Move the idxadr of the RCB of the moved record. */			fmpShiftIdxAdrRCB(rcb, TSD_SIA_RC2_M1, 1, nrec, 1);			return E_OK;		}		if ( (ridx->type[0] == 0) && (ridx->type[1] != 0) ) {			arec++;		}	}	/* Find an unused index from before the current record index. */	for ( i = cur - 1; i >= top; --i ) {		ridx = &ri->mapbase[i];		if ( (ridx->type[0] == 0) && (ridx->type[1] == 0) ) {			/* Move index to make a space at the location of cur. */			nrec = shiftUpRIdx(ri->mapbase, i, cur);			fmpSetRIdxMapFlag(ri, MD_WRITE);			/* Move the idxadr of the RCB of the moved record. */			fmpShiftIdxAdrRCB(rcb, TSD_SIA_RC2_M1, -(nrec - 1), 0, TSD_SIA_RC5_M1);			/* Since the current record index moved to the previous location,			   move ri to the previous location as well. */			ri->adr.ridx.offset = (VP)((VB*)ri->adr.ridx.offset - sizeof(DfRecordIndex));			ri->mapadr--;			return E_OK;		}	}	/* Add the block for new record index. */	err = appendRIdxBlock(ri, rcb, arec);	if ( err < E_OK ) {		goto err_ret;	}	nrec = (W)err;	/* Divide the current record index block. */	err = divideRIdxBlock(ri, cur + 1);	if ( err < E_OK ) {		goto err_ret;	}	nrec += (W)err;	/* Make invalid the RCBs of records moved between the index blocks. */	fmpSetInvalidRCB(rcb, 1, nrec);	return E_OK;err_ret:	DEBUG_PRINT(("appendRIdx err = %d\n", err));	return err;}/* * Add the record index. *	Add new record index just after the current location of ri. *	The added record index is cleared to 0 *	Define the location of newly added record index as the current location of ri. *	Return the address of newly added record index. */EXPORT DfRecordIndex* fmpAppendRIdx( RIdx *ri, RCB *rcb ){	DfRecordIndex	*ridx;	ER		err;	/* Add the record index. */	err = appendRIdx(ri, rcb);	if ( err < E_OK ) {		goto err_ret;	}	err = fmpCheckDiskError(ri->ofcb, ri->ofcb->fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	/* Advance the current location by one. (Locate it at the added record.) */	ridx = fmpGetRIdx(ri);	ri->cp = 0;	return ridx;err_ret:	/* Make invalid all RCBs for safety. */	fmpSetInvalidAllRCB(ri->ofcb);	DEBUG_PRINT(("fmpAppendRIdx err = %d\n", err));	ri->err = err;	return NULL;}/* * Insert the record index. *	Insert the new record index at the current location of ri. *	The inserted record index is cleared to 0 *	The current location of ri is the location of inserted record index. */LOCAL ER insertRIdx( RIdx *ri, RCB *rcb ){	DfRecordIndex	*ridx;	W		cur, top, end, i, k;	W		nrec, arec;	ER		err;	cur = (ri->mapadr - ri->mapbase) - 1;	top = (W)TopRIdx(ri->ofcb->idxlv, ri->ofcb);	end = (W)(ri->ofcb->fsinfo->sblk / sizeof(DfRecordIndex));	/* 1 when the current location of ri is a normal index/link index. */	k = ( ri->mapbase[cur].type[0] == 0 )? 1: 0;	arec = 0;  /* Record count after the current record. */	/* Find an unused index from after the current record index. */	for ( i = cur + 1; i < end; ++i ) {		ridx = &ri->mapbase[i];		if ( (ridx->type[0] == 0) && (ridx->type[1] == 0) ) {			/* Move index to make a space at the location of cur.  */			nrec = shiftDownRIdx(ri->mapbase, cur, i);			fmpSetRIdxMapFlag(ri, MD_WRITE);			/* Move the idxadr of the RCB of the moved record. */			fmpShiftIdxAdrRCB(rcb, TSD_SIA_RC2_M1, 1 - k, nrec - k, 1);			return E_OK;		}		if ( (ridx->type[0] == 0) && (ridx->type[1] != 0) ) {			arec++;		}	}	/* Find an unused index from before the current record index. */	for ( i = cur - 1; i >= top; --i ) {		ridx = &ri->mapbase[i];		if ( (ridx->type[0] == 0) && (ridx->type[1] == 0) ) {			/* Move index to make a space just before cur. */			nrec = shiftUpRIdx(ri->mapbase, i, cur - 1);			fmpSetRIdxMapFlag(ri, MD_WRITE);			/* Move the idxadr of the RCB of the moved record. */			fmpShiftIdxAdrRCB(rcb, TSD_SIA_RC2_M1, -(nrec - 1) - k, 0 - k, TSD_SIA_RC5_M1);			/* Since the inserted new index is in the previous location,			   move ri to the previous location as well. */			ri->adr.ridx.offset = (VP)((VB*)ri->adr.ridx.offset - sizeof(DfRecordIndex));			ri->mapadr--;			return E_OK;		}	}	/* Add the block for new record index. */	err = appendRIdxBlock(ri, rcb, arec);	if ( err < E_OK ) {		goto err_ret;	}	nrec = (W)err;	/* Divide the current record index block. */	err = divideRIdxBlock(ri, cur);	if ( err < E_OK ) {		goto err_ret;	}	nrec += (W)err;	/* Make invalid the RCBs of records moved between the index blocks. */	fmpSetInvalidRCB(rcb, 1 - k, nrec - k);	return E_OK;err_ret:	DEBUG_PRINT(("insertRIdx err = %d\n", err));	return err;}/* * Insert the record index. *	Insert the new record index at the current location of ri. *	The inserted record index is cleared to 0 *	Define the location of newly inserted record index as the current location of ri. *	Return the address of newly inserted record index. */EXPORT DfRecordIndex* fmpInsertRIdx( RIdx *ri, RCB *rcb ){	ER		err;	/* Insert the record index. */	err = insertRIdx(ri, rcb);	if ( err < E_OK ) {		goto err_ret;	}	err = fmpCheckDiskError(ri->ofcb, ri->ofcb->fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	ri->cp = 0;	return ri->mapadr - 1;err_ret:	/* Make invalid all RCBs for safety. */	fmpSetInvalidAllRCB(ri->ofcb);	DEBUG_PRINT(("fmpInsertRIdx err = %d\n", err));	ri->err = err;	return NULL;}/* ------------------------------------------------------------------------ *//* * Change the record count of the indirect index. *	Increase/Decrease the record count recorded in the indirect index *	of the path of *idxadr by diff. */LOCAL ER changeRecordCountIIdx( IdxAdr *idxadr, W diff, OFCB *ofcb ){	FsInfo		*fsinfo = ofcb->fsinfo;	DfIndirectIndex	*iidx;	W		i;	W		n;	ID		mid;	ER		err;	for ( i = 0; i < ofcb->idxlv; ++i ) {		iidx = fmpMapDskAdr(idxadr->iidx[i], sizeof(DfIndirectIndex),							ofcb, &mid, fsinfo);		if ( iidx == NULL ) {			err = (ER)mid;			goto err_ret;		}		n = (W)fmpConvEndianW(iidx->nrec, fsinfo) + diff;		iidx->nrec = fmpConvEndianW((UW)n, fsinfo);		fmpUnmapDisk(mid, MD_WRITE);	}	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("changeRecordCountIIdx err = %d\n", err));	return err;}/* * Set the record index. *	Set the record index at the current location of ri as a normal index or link index. *	The set record index must be unused index cleared to 0. * *	lnk is used only when setting the link index. */EXPORT ER fmpSetRIdx( RIdx *ri, W rtype, UH stype, LINK *lnk ){	DfRecordIndex	*ridx = ri->mapadr - 1;	OFCB		*ofcb = ri->ofcb;	FsInfo		*fsinfo = ofcb->fsinfo;	ER		err;	/* Set the indirect index to "record added." */	err = changeRecordCountIIdx(&ri->adr, +1, ofcb);	if ( err < E_OK ) {		goto err_ret;	}	/* Set the record index. */	if ( isLinkRecord(rtype) != 0 ) {		/* When it is the link index. */		ridx->l.always80 = TSD_FSI_ALW_0X80;		ridx->l.stype    = fmpConvEndianH(stype, fsinfo);		ridx->l.fid      = fmpConvEndianH(lnk->f_id, fsinfo);		ridx->l.atr[TSD_FSI_POS_0]   = fmpConvEndianH(lnk->atr1, fsinfo);		ridx->l.atr[TSD_FSI_POS_1]   = fmpConvEndianH(lnk->atr2, fsinfo);		ridx->l.atr[TSD_FSI_POS_2]   = fmpConvEndianH(lnk->atr3, fsinfo);		ridx->l.atr[TSD_FSI_POS_3]   = fmpConvEndianH(lnk->atr4, fsinfo);		ridx->l.atr[TSD_FSI_POS_4]   = fmpConvEndianH(lnk->atr5, fsinfo);	} else {		/* When it is the normal index. */		ridx->n.rtype    = (UB)rtype | TSD_FSI_RTY_0X80;		ridx->n.stype    = fmpConvEndianH(stype, fsinfo);	}	fmpSetRIdxMapFlag(ri, MD_WRITE);	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpSetRIdx err = %d\n", err));	ri->err = err;	return err;}/* ------------------------------------------------------------------------ *//* * Delete the record index block. *	Delete the index block at the current location of ri. * *	Although current location of ri become undecided, the next record index *	can be read in the next reading (fmpGetRIdx/fmpGetDataBlkAdr). *	(Similar state to the state just after fmpOpenRIdx) */LOCAL ER deleteRIdxBlock( RIdx *ri ){	IdxAdr		idxadr;	W		delblk;	LogAdr		ladr;	DfIndirectIndex	*iidx, *base, *end;	BOOL		empty;	W		i;	OFCB		*ofcb = ri->ofcb;	FsInfo		*fsinfo = ofcb->fsinfo;	ID		mid;	ER		err;	/* Index block to be deleted */	idxadr = fmpGetIdxAdr(ri);	delblk = (W)ri->lblk;	/* Move the current location of ri to the next index block. */	err = gotoNextRIdxBlk(ri);	if ( (err < E_OK) && (err != E_ILFMT) ) {		goto err_ret;	}	ri->cp = TSD_RID_CP_5;	/* Delete */	for ( i = ofcb->idxlv - 1; i >= 0; --i ) {		ladr = fmpDAdrToLAdr(idxadr.iidx[i], fsinfo);		/* Map the indirect index block. */		base = fmpMapLogBlk(ladr.blk, ofcb, &mid, fsinfo);		if ( base == NULL ) {			err = (ER)mid;			goto err_ret;		}		/* Delete the entry from the indirect index. */		iidx = (DfIndirectIndex*)((VB*)base + ladr.offset);		iidx->blk = 0;		/* Whether the indirect index block becomes free. */		iidx = &base[TopIIdx(i, ofcb)];		end  = (DfIndirectIndex*)((VB*)base + fsinfo->sblk);		empty = TRUE;		while ( iidx < end ) {			if ( iidx->blk != 0U ) {				empty = FALSE;				break;			}			iidx++;		}		if ( empty && (i == 0) ) {			/* Since the index of the file header becomes free,			   restore the index level to 0. */			DfFileHeader *fh = (DfFileHeader*)base;			fh->idxlv = 0;			ofcb->idxlv = 0;		}		fmpUnmapDisk(mid, MD_WRITE);		err = fmpCheckDiskError(ofcb, fsinfo);		if ( err < E_OK ) {			goto err_ret;		}		/* Release the block. */		err = fmpFreeOneBlock((UW)delblk, ofcb, fsinfo);		if ( err < E_OK ) {			goto err_ret;		}		if ( !empty ) {			break;		}		delblk = (W)ladr.blk;	}	return E_OK;err_ret:	DEBUG_PRINT(("deleteRIdxBlock err = %d\n", err));	return err;}/* * Delete the record index. *	Delete the record index at the current location of ri. *	The record index must not include the data block. */EXPORT ER fmpDeleteRIdx( RIdx *ri ){	DfRecordIndex	*ridx;	DfRecordIndex	*end;	OFCB		*ofcb = ri->ofcb;	FsInfo		*fsinfo = ofcb->fsinfo;	ER		err;	ridx = ri->mapadr - 1;	if ( (ridx->type[0] == 0) && (ridx->type[1] != 0) ) {		/* Set the indirect index to "record deleted." */		err = changeRecordCountIIdx(&ri->adr, TSD_FDR_VAL_M1, ofcb);		if ( err < E_OK ) {			goto err_ret;		}	}	/* Make the current record index unused. */	memset(ridx, 0, (size_t)sizeof(DfRecordIndex));	fmpSetRIdxMapFlag(ri, MD_WRITE);	/* Whether the whole record index becomes free. */	ridx = &ri->mapbase[TopRIdx(ofcb->idxlv, ofcb)];	end = (DfRecordIndex*)((VB*)ri->mapbase + fsinfo->sblk);	while ( ridx < end ) {		if ( !((ridx->type[0] == 0) && (ridx->type[1] == 0)) ) {			/* Not free */			break;		}		ridx++;	}	err = fmpCheckDiskError(ofcb, fsinfo);	if ( err < E_OK ) {		goto err_ret;	}	if ( ridx >= end ) {		/* Since it became free, delete the index block. */		err = deleteRIdxBlock(ri);		if ( err < E_OK ) {			goto err_ret;		}	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpDeleteRIdx err = %d\n", err));	ri->err = err;	return err;}/* * Delete the date block. *	Release from top th byte to just before end th byte of the block indicated by *	the data block address at the current location of ri. The data block *	address of the record index is changed to leave only the part before top th byte. *	When end is not a boundary of the logical block, it must be *	at the separator code of fragment. *	When top is the start of the record data (Make the record size 0), *	it must be that topf = TRUE. *	When the whole record index becomes free, the record index is also deleted. *	(Only when it is connection index.) */EXPORT ER fmpDeleteDataBlk( RIdx *ri, W top, W end, BOOL topf ){	DfRecordIndex	*ridx;	W		cp;	LogBlk		lblk;	W		useblk;	W		i, c;	ER		err;	/* Current record index. */	ridx = fmpGetMapAdr(ri, &cp);	/* Data block address */	lblk = fmpConvEndianLogBlk(ridx->c.blk[cp], ri->ofcb->fsinfo);	/* Release data block */	useblk = fmpFreeDataBlk(lblk, top, end, topf, ri->ofcb);	if ( useblk < E_OK ) {		err = (ER)useblk;		goto err_ret;	}	fmpSetRIdxMapFlag(ri, MD_WRITE);	if ( useblk > 0 ) {		ridx->c.blk[cp].cnt = useblk;	/* Remaining block count */	} else {		*(UW*)&ridx->c.blk[cp] = 0;	/* Delete all. */		/* Whether the whole record index becomes free. */		c = 0;		for ( i = 0; i < TSD_FDB_VAL_4; ++i ) {			c += ridx->c.blk[i].cnt;		}		if ( (c == 0) && (ridx->type[1] == 0) ) {			/* Delete the record index. */			err = fmpDeleteRIdx(ri);			if ( err < E_OK ) {				goto err_ret;			}		}	}	return E_OK;err_ret:	DEBUG_PRINT(("fmpDeleteDataBlk err = %d\n", err));	ri->err = err;	return err;}

⌨️ 快捷键说明

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