Esempio n. 1
0
void bfs(edge_index_t *edge_begin, 
	 edge_index_t *edge_end,
	 node_index_t *dst,
         node_index_t starting_node,
	 level_t *level,
         edge_index_t *level_counts) {
  node_index_t queue[N_NODES];
  node_index_t q_in, q_out;
  node_index_t dummy;
  node_index_t n;
  edge_index_t e;

  /*init_levels: for( n=0; n<N_NODES; n++ )*/
  /*level[n] = MAX_LEVEL;*/
  /*init_horizons: for( i=0; i<N_LEVELS; i++ )*/
  /*level_counts[i] = 0;*/

  q_in = 1;
  q_out = 0;
  level[starting_node] = 0;
  level_counts[0] = 1;
  Q_PUSH(starting_node);

  loop_queue: for( dummy=0; dummy<N_NODES; dummy++ ) { // Typically while(not_empty(queue)){
    if( Q_EMPTY() )
      break;
    n = Q_PEEK();
    Q_POP();
    edge_index_t tmp_begin = edge_begin[n];
    edge_index_t tmp_end = edge_end[n];
    loop_neighbors: for( e=tmp_begin; e<tmp_end; e++ ) {
      node_index_t tmp_dst = dst[e];
      level_t tmp_level = level[tmp_dst];

      if( tmp_level ==MAX_LEVEL ) { // Unmarked
        level_t tmp_level = level[n]+1;
        level[tmp_dst] = tmp_level;
        ++level_counts[tmp_level];
        Q_PUSH(tmp_dst);
      }
    }
  }

  /*
  printf("Horizons:");
  for( i=0; i<N_LEVELS; i++ )
    printf(" %d", level_counts[i]);
  printf("\n");
  */
}
Esempio n. 2
0
/* schedule: adds a given symbol to the appropriate queue depending
   upon its type.  Formulae are added to the formula queue; actions
   are added to the action queue if they have sources (ie if it is a
   "triggered action" -- proc p:v {} is a triggered action, proc p {}
   is not); other types are ignored.

   If it is already in the queue, then move it to the end, so
   duplicates do not appear.  This rule does not apply in dtkeden if
   synchronize is on.  In this case, we may want to faithfully enact
   each redefinition, as they may be coming from another machine, even
   if we have not managed to finish evaluating the queue yet.  Hence
   duplicates are allowed in this case.

   [Ash] */
static void
schedule(symptr sp)
{
    register symptr_ATOM P;
    register symptr_QUEUE *Q;
#ifdef DISTRIB
    extern Int *synchronize;
#endif /* DISTRIB */

    switch (sp->stype) {
    case FORMULA:
        DEBUGPRINT("FQUEUE schedule %s\n", sp->name);
	Q = &formula_queue;
	break;

    case BLTIN:
    case PROCEDURE:
    case FUNCTION:
    case PROCMACRO:
        DEBUGPRINT("AQUEUE schedule %s\n", sp->name);
	Q = &action_queue;
	break;

    default:
        /* If VAR, for example */
        DEBUGPRINT2("schedule: not scheduling %s %s\n", typename(sp->stype),
		    sp->name);
	return;			/* don't queue up */
    }

/*
    if (P = SEARCH_symptr(Q, sp, 1)) {
*/
#ifdef DISTRIB
    if ((P = sp->Qloc) && !*synchronize)
      /* This may raise a problem in a distributed or synchronized
	environment, because some information will be missed. For
	example, if we want to make a train move smoothly, we need to
	show every slight move. But this reschedule may make previous
	movements disappear. So we take synchronization into account
	--sun */
#else
    if ((P = sp->Qloc))
#endif /* not DISTRIB */

    {
	/* Already there --> reschedule */
	DELETE_ATOM(Q, P);
	APPEND_Q(Q, P);
    } else {
	/* Not there --> put it at the end */
	switch (sp->stype) {
	case FORMULA:
	    APPEND_symptr_Q(Q, sp);
	    sp->Qloc = Q->prev;
	    break;

	case BLTIN:
	case PROCEDURE:
        case PROCMACRO:
	case FUNCTION:		/* if it's an action */
	    if (!Q_EMPTY(&sp->sources)) {
		APPEND_symptr_Q(Q, sp);
		sp->Qloc = Q->prev;
	    }
	    break;
	}
    }
}