Ejemplo n.º 1
0
void loopExists(Trav *t) {
    Node *n = &elem(t->match);
    success = 0;
    if (availableLoops(n) > 0) {
        matchLoop(n);
        success = 1;
    }
}
Ejemplo n.º 2
0
void Trace::fastCompressLoop(int window){
  static int warned_once = 0;
  int distance;

  int head_flag;      /* Whether target head has been found. */
  int match_flag;     /* Whether a node matching target head has been found. */
  int found_flag;     /* */

  int target_length=1, merge_length=1;

  Event *target_tail = NULL;
  Event *target_head = NULL;
  Event *merge_tail = NULL;
  Event *merge_head = NULL;

  distance = 0;
  head_flag = 0;
  found_flag = 1;

  do {
    target_tail = tail;

    if(found_flag || !head_flag) {
      /* if the found flag is set - start a new search */
      target_head = target_tail;
      distance = 0;
      target_length = merge_length = 1;
    } else {
      /* otherwise continue a previous search */
      target_head = target_head->prev;
      target_length++;
      merge_length = 1;
    }

    head_flag = 0;
    match_flag = 0;
    found_flag = 0;


    /* Search backwards in the queue until we find a match with the target tail.
			After this loop is done, either head_flag will be false (and nothing found)
			or the head will be just after the matching tail.
     */
    while(target_head->prev != NULL && (window == -1 || window > distance)) {
      if( !target_head->checkLoc(MEMBER)
          && target_tail->sigMatch(target_head->prev)
          && target_tail->opMatch(target_head->prev)){
        head_flag = 1;
        break;
      }
      target_head = target_head->prev;
      target_length++;
      distance++;
    }

    /* didn't find head: can skip the rest. */
    if (!head_flag) {
      /* Warn if the window was exceeded, but only warn once. */
      if(!warned_once && window != -1 && window <= distance) {
        fprintf(stderr, "warning: window exceeded - possible compression missed (window set at %d)\n", window);
        fflush(stderr);
        warned_once = 1;
      }
      continue;
    }

    /* If the head flag is true, we've got the target_tail, the target_head, and the merge_tail (just before target_head).
		Now we can try to find a match for the target_head somewhere before the merge tail.  This will be merge_head.*/
    merge_head = target_head->prev;
    merge_tail = target_head->prev;

    while(merge_head != NULL) {
      if( !merge_head->checkLoc(MEMBER)
          && merge_head->sigMatch(target_head)
          && merge_head->opMatch(target_head)
          && (merge_length == target_length)
      ) {
        match_flag = 1;
        break;
      }
      merge_head = merge_head->prev;
      merge_length++;
    }

    /* check lengths of sequences and avoid a traversal if there's clearly no match */
    if(merge_length != target_length ){
      continue;
    }

    /* If we didn't find the merge head, we know there's no match in the sequence. Bail. */
    if(!match_flag) continue;

    // Make sure the sequences [target_head .. target_tail] and [merge_head .. merge_tail] match.
    if (!matchLoop(merge_head, merge_tail, merge_length, target_head, target_tail, target_length)) {
      continue;
    } else {
      found_flag = 1;
      mergeLoopEvents(merge_head, merge_tail, target_head, target_tail);
      // this adjusts prsd info in the merge sequence to reflect the new loop we're adding
      updateLoopInfo(merge_head, merge_tail, target_head, target_tail, merge_length);
      // if the compression was successful, go through and free all the target nodes from the end
      // of the seqence.
      deleteTail(merge_tail);
    }

  } while(head_flag || found_flag);

} /* fastCompressLoop */