Пример #1
0
/*! \brief Obtention depuis le fichier du bloc contenant l'enregistrement
 * d'indice-fichier donné.
 * 
 *  \ingroup cache_internal
 *
 * Cette fonction retourne un bloc valide contenant l'enregistrement cherché.
 * On cherche d'abord l'enregistrement dans le cache grâce à Find_Block.  Si on
 * ne l'y trouve pas, on obtient un bloc libre grâce à la fonction
 * Strategy_Replace_Block (qui, comme son nom l'indique, depend de la
 * strategie). On sauve ce bloc si il est marqué modifié puis on initialise son
 * entête et on lit son contenu depuis le fichier (Read_Block).
 *
 * \param pcache un pointeur sur le cache à synchroniser
 * \param irfile indice du bloc cherché dans le fichier
 * \return un pointeur sur l'entête du bloc (ou le pointeur nul si le bloc n'est pas trouvé)  
*/
struct Cache_Block_Header *Get_Block(struct Cache *pcache, int irfile)
{
    struct Cache_Block_Header *pbh;

    if ((pbh = Find_Block(pcache, irfile)) == NULL)
    {
        /* L'enregistrement n'est pas dans le cache */
        
        /* On demande un block à Strategy_Replace_Block */
	pbh = Strategy_Replace_Block(pcache);
	if (pbh == NULL) return NULL;

	/* Si le bloc libéré est valide et modifié, on le sauve sur le fichier */
	if ((pbh->flags & VALID) && (pbh->flags & MODIF)
            && (Write_Block(pcache, pbh) != CACHE_OK))
	    return NULL; 
	
        /* On remplit le bloc libre et son entête avec l'information de
         * l'enregistrement d'indice-fichier irfile
         */
	pbh->flags = 0;
	pbh->ibfile = irfile / pcache->nrecords; /* indice du bloc dans le fichier */
	if (Read_Block(pcache, pbh) != CACHE_OK) return NULL;
    }

    /* Soit l'enregistrement était déjà dans le cache, soit on vient de l'y mettre */
    return pbh;
}
Пример #2
0
*/	static REBCNT Parse_To(REBPARSE *parse, REBCNT index, REBVAL *item, REBFLG is_thru)
/*
**		Parse TO a specific:
**			1. integer - index position
**			2. END - end of input
**			3. value - according to datatype
**			4. block of values - the first one we hit
**
***********************************************************************/
{
	REBSER *series = parse->series;
	REBCNT i;
	REBSER *ser;

	// TO a specific index position.
	if (IS_INTEGER(item)) {
		i = (REBCNT)Int32(item) - (is_thru ? 0 : 1);
		if (i > series->tail) i = series->tail;
	}
	// END
	else if (IS_WORD(item) && VAL_WORD_CANON(item) == SYM_END) {
		i = series->tail;
	}
	else if (IS_BLOCK(item)) {
		i = To_Thru(parse, index, item, is_thru);
	}
	else {
		if (IS_BLOCK_INPUT(parse)) {
			REBVAL word; /// !!!Temp, but where can we put it?
			if (IS_LIT_WORD(item)) {  // patch to search for word, not lit.
				word = *item;
				VAL_SET(&word, REB_WORD);
				item = &word;
			}
			///i = Find_Value(series, index, tail-index, item, 1, (REBOOL)(PF_CASE & flags), FALSE, 1);
			i = Find_Block(series, index, series->tail, item, 1, HAS_CASE(parse)?AM_FIND_CASE:0, 1);
			if (i != NOT_FOUND && is_thru) i++;
		}
		else {
			// "str"
			if (ANY_BINSTR(item)) {
				if (!IS_STRING(item) && !IS_BINARY(item)) {
					// !!! Can this be optimized not to use COPY?
					ser = Copy_Form_Value(item, 0);
					i = Find_Str_Str(series, 0, index, series->tail, 1, ser, 0, ser->tail, HAS_CASE(parse));
					if (i != NOT_FOUND && is_thru) i += ser->tail;
				}
				else {
					i = Find_Str_Str(series, 0, index, series->tail, 1, VAL_SERIES(item), VAL_INDEX(item), VAL_LEN(item), HAS_CASE(parse));
					if (i != NOT_FOUND && is_thru) i += VAL_LEN(item);
				}
			}
			// #"A"
			else if (IS_CHAR(item)) {
				i = Find_Str_Char(series, 0, index, series->tail, 1, VAL_CHAR(item), HAS_CASE(parse));
				if (i != NOT_FOUND && is_thru) i++;
			}
		}
	}

	return i;
}