Пример #1
0
/**
 * Caches the given token sequence in the given cache. Note that
 * match is supposed to contain a single match, not a match list.
 */
static void cache_match_internal(struct match_list* match,const int* tab,int start,int end,LocateCache *c,Abstract_allocator prv_alloc) {
int token=-1;
struct match_list* m=match;
if (start<=end) {
	token=tab[start];
	m=NULL;
}
/* No node */
if (*c==NULL) {
	*c=new_LocateCache(token,m,prv_alloc);
	if (token!=-1) {
		cache_match_internal(match,tab,start+1,end,&((*c)->middle),prv_alloc);
	}
	return;
}
/* There is a node */
if (token<(*c)->token) {
	/* If we have to move on the left */
	return cache_match_internal(match,tab,start,end,&((*c)->left),prv_alloc);
}
if (token>(*c)->token) {
	/* If we have to move on the right */
	return cache_match_internal(match,tab,start,end,&((*c)->right),prv_alloc);
}
/* We have the correct token */
if (token==-1) {
	/* If we are in a final node that already existed, we just add
	 * the new match at the end of the match list to get the same match order as
	 * if the cache system had not been used, but only if the match is not already present */
	struct match_list* *ptr=&((*c)->matches);
	struct match_list* z;
	match->next=NULL;
	while ((*ptr)!=NULL) {
		z=*ptr;
		if (compare_matches(&(z->m),&(match->m))==A_EQUALS_B &&
				!u_strcmp(z->output,match->output)) {
			/* We discard a match that was already in cache */
			free_match_list_element(match,prv_alloc);
			return;
		}
		ptr=&((*ptr)->next);
	}
	(*ptr)=match;
	return;
}
cache_match_internal(match,tab,start+1,end,&((*c)->middle),prv_alloc);
}
Пример #2
0
/**
 * This function removes all non ambiguous outputs from the given match list.
 * If renumber is non NULL, we have renumber[x]=y, where x is the position
 * of a match in the filtered list, and y its corresponding number in the
 * unfiltered original one.
 */
void filter_unambiguous_outputs(struct match_list* *list,vector_int* renumber) {
struct match_list* tmp;
if (*list==NULL) return;
struct match_list* previous=NULL;
struct match_list* l=*list;
int previous_was_identical=0;
int original_match_number=-1;
while (l!=NULL) {
  original_match_number++;
  if (previous==NULL) {
    /* Case 1: we are at the beginning of the list */
    /* Case 1a: there is only one cell */
    if (l->next==NULL) {
      free_match_list(l);
      *list=NULL;
      return;
    }
    /* Case 1b: there is a next cell, but it's not ambiguous with the current one */
    if (!are_ambiguous(l,l->next)) {
      /* We have to delete the current cell */
      tmp=l->next;
      free_match_list_element(l);
      l=tmp;
      continue;
    }
    /* Case 1c: the next cell is an ambiguous one, we can move on */
    /* Now we know the list head element */
    *list=l;
    previous=l;
    previous_was_identical=1;
    l=l->next;
    vector_int_add(renumber,original_match_number);
    continue;
  } else {
    /* Case 2: there is a previous cell */
    if (previous_was_identical) {
      vector_int_add(renumber,original_match_number);
      /* Case 2a: we know that we have to keep this current cell, but
       * we must check if the next is also an ambiguous one */
      if (l->next==NULL) {
        /* No next cell ? We're done then */
        return;
      }
      previous_was_identical=are_ambiguous(l,l->next);
      previous=l;
      l=l->next;
      continue;
    }
    /* Case 2b: previous cell is different, so we have to test the next one
     * to know whether we must keep the current one or not */
    if (l->next==NULL) {
      /* No next cell ? We have to delete the current one and then
       * we are done */
      free_match_list_element(l);
      previous->next=NULL;
      return;
    }
    previous_was_identical=are_ambiguous(l,l->next);
    if (previous_was_identical) {
      /* We have to keep the current cell */
      previous=l;
      l=l->next;
      vector_int_add(renumber,original_match_number);
      continue;
    }
    /* Final case, the next cell is not ambiguous, so we have to delete
     * the current one */
    tmp=l;
    l=l->next;
    free_match_list_element(tmp);
    previous->next=l;
    continue;
  }
}
}