Exemplo n.º 1
0
void Graph::dfs(const string &node, int &time)
{
    adjacency_list::iterator e;
    neighbor_list *neighbors;

    if (finished)
        return;

    visited[node] = true;
    time = time + 1;
    entry_time[node] = time;

    if (adj_list.find(node) != adj_list.end()) {
        neighbors = adj_list[node];
        for (neighbor_list::iterator it = neighbors->begin();
             it != neighbors->end();
             ++it) {
            if (visited.find(it->first) == visited.end()) {
                parent[it->first] = node;
                process_edge(node, it->first);
                dfs(it->first, time);
            } else {
                process_edge(node, it->first);
            }
        }
    }

    time = time + 1;
    processed[node] = true;
}
Exemplo n.º 2
0
 void LinearizerBase::process_edge(int iv1, int iv2, int marker)
 {
   int mid = peek_vertex(iv1, iv2);
   if(mid != -1)
   {
     process_edge(iv1, mid, marker);
     process_edge(mid, iv2, marker);
   }
   else
     add_edge(iv1, iv2, marker);
 }
Exemplo n.º 3
0
bfs(graph *g, int start)
{
	queue q;			/* queue of vertices to visit */
	int v;				/* current vertex */
	int i;				/* counter */

	init_queue(&q);
	enqueue(&q,start);
	discovered[start] = TRUE;

	while (empty(&q) == FALSE) {
		v = dequeue(&q);
		process_vertex_early(v);
		processed[v] = TRUE;
		for (i=0; i<g->degree[v]; i++) 
		    if (valid_edge(g->edges[v][i]) == TRUE) {
			if (discovered[g->edges[v][i]] == FALSE) {
				enqueue(&q,g->edges[v][i]);
				discovered[g->edges[v][i]] = TRUE;
				parent[g->edges[v][i]] = v;
			}
			if (processed[g->edges[v][i]] == FALSE) 
				process_edge(v,g->edges[v][i]);
		    }
		process_vertex_late(v);
	}
}
Exemplo n.º 4
0
dfs(graph *g, int v)
{
	int i;				/* counter */
	int y;				/* successor vertex */

	if (finished) return;		/* allow for search termination */

	discovered[v] = TRUE;
	process_vertex_early(v);

	for (i=0; i<g->degree[v]; i++) {
		y = g->edges[v][i];
		if (valid_edge(g->edges[v][i]) == TRUE) {
			if (discovered[y] == FALSE) {
				parent[y] = v;
				dfs(g,y);
			} else 
				if (processed[y] == FALSE)
					process_edge(v,y);
		}
		if (finished) return;
	}

	process_vertex_late(v);
	processed[v] = TRUE;
}
Exemplo n.º 5
0
void Graph::bfs_worker(int start, void(*process_vertex_early)(int v), 
				void(*process_vertex_late)(int v), void(*process_edge)(int v, EdgeNode *p))
{
	queue<int> q;
	int v;
	int y;
	EdgeNode *p;

	q.push(start);
	discovered[start] = TRUE;

	while(q.empty() == FALSE){
		v = q.front();
		q.pop();
		process_vertex_early(v);
		processed[v] = TRUE;
		p = this->edges[v];
		while(p){
			y = p->y;
			if(processed[y] == FALSE || this->directed)
				process_edge(v,p);
			if(discovered[y] == FALSE){
				q.push(y);
				discovered[y] = TRUE;
				parent[y] = v;
			}
			p = p->next;
		}
		process_vertex_late(v);
	}
}
Exemplo n.º 6
0
  // process all elements of the mesh
  for_all_active_elements(e, mesh)
  {
    sln->set_active_element(e);
    sln->set_quad_order(0, item);
    scalar* val = sln->get_values(ia, ib);
    if (disp)
    {
      xdisp->set_active_element(e);
      ydisp->set_active_element(e);
    }

    int iv[4];
    for (unsigned int i = 0; i < e->nvert; i++)
      iv[i] = get_top_vertex(id2id[e->vn[i]->id], getval(i));

    // we won't bother calculating physical coordinates from the refmap if this is not a curved element
    curved = e->is_curved();
    cmax = e->get_diameter();

    // recur to sub-elements
    if (e->is_triangle())
      process_triangle(iv[0], iv[1], iv[2], 0, NULL, NULL, NULL, NULL);
    else
      process_quad(iv[0], iv[1], iv[2], iv[3], 0, NULL, NULL, NULL, NULL);

    for (unsigned int i = 0; i < e->nvert; i++)
      process_edge(iv[i], iv[e->next_vert(i)], e->en[i]->marker);
  }
Exemplo n.º 7
0
void bfs(graph *g, int start)
{
	queue q;			/* queue of vertices to visit */
	int v;				/* current vertex */
	int y;				/* successor vertex */
	edgenode *p;		/* temporary pointer */

	init_queue(&q);
	enqueue(&q,start);
	discovered[start] = TRUE;

	while (empty_queue(&q) == FALSE) {
		v = dequeue(&q);
		processed[v] = TRUE;
		p = g->edges[v];
		while (p != NULL) {
		    y = p->y;
		    if ((processed[y] == FALSE) || g->directed)
				process_edge(v,y);
		    if (discovered[y] == FALSE) {
				enqueue(&q,y);
				discovered[y] = TRUE;
				parent[y] = v;
		    }
		    p = p->next;
		}
	}
}
Exemplo n.º 8
0
int process_vertex(int v)
{
		int i;
		bool valid_vertex=0;
        /* Evitamos los cálculos en el nodo si éste ha sido marcado como "congelado" (Alg. Rec.)*/
        /* Igualmente, no calculamos los nodos invalidos */

            /* Acumula el consumo total (Y002) por los receptores y guarda dicho valor en el nodo */
            for (i=0; i< g.degree[v]; i++){
                fprintf(flog,"Agregando consumo para nodo %s\n",n[v].label);
                n[v].utilizacion += g.consumo[v][i];
                fprintf(flog,"Utilizacion = %.4f\n",n[v].utilizacion);
            }

            /* Revisa que la utilizacion no sea mayor que la capacidad cuando existe capacidad limitante */
            if(n[v].flag_capacity){
                // Reducimos la capacidad para evitar fugas de dinero
                // Usando fabs() estaba generando una alerta ??
                double diff = abs(n[v].utilizacion - n[v].capacidad) / n[v].capacidad;
                if( diff < TOLERANCIA){
                    fprintf(flog,"Ajustando capacidad de nodo %d de %.2f a %.2f\n",v,n[v].capacidad,n[v].utilizacion);
                    n[v].capacidad = n[v].utilizacion;
                } else {
                    printf("Nodo %s tiene capacidad no utilizada.\nUtilizacion: %.2f\nCapacidad: %.2f\n",
                           n[v].label, n[v].utilizacion, n[v].capacidad);
                }

                if (n[v].utilizacion > n[v].capacidad) {
                    printf("Utilizacion %.2f excede capacidad %.2f para nodo %d con capacidad limitante\n",n[v].utilizacion,n[v].capacidad,v);
                    exit(EXIT_FAILURE);
                }
            } else {     // Nodo no tiene capacidad limitante -- su utilización es su capacidad
                n[v].capacidad = n[v].utilizacion;
            }

            /* Calcula tasa fija (RT01) y proporcional (RT02) para el nodo y guarda dicho valor en el nodo */
            if(n[v].capacidad){
                n[v].tasa_fija 			= (n[v].costo_primario_fijo + n[v].costo_secundario_fijo) / n[v].capacidad;
            }

            if(n[v].utilizacion) {
                n[v].tasa_proporcional 	= (n[v].costo_primario_proporcional + n[v].costo_secundario_proporcional) / n[v].utilizacion;
            }
        /* Procesamos las aristas que salen del nodo */
		for (i=0; i< g.degree[v]; i++)
			if (valid_edge(v,i))			/* Verifica que el consumo sea mayor a cero */
					process_edge(v,i);		/* Calcula costos secundarios y los acumula en la estructura del nodo receptor */

		fprintf(flog,"Se proceso el nodo %d (congelado=%d)\n",v,n[v].congelar_tasas);
		n[v].flag_tasa=1;
		return 0;
}
Exemplo n.º 9
0
zebra_symbol_type_t zebra_scanner_new_scan (zebra_scanner_t *scn)
{
    /* finalize outstanding edge */
    zebra_symbol_type_t edge = process_edge(scn, 0);

    /* reset color to SPACE
     * (actually just resets everything)
     */
    memset(&scn->x, 0, sizeof(zebra_scanner_t) + (void*)scn - (void*)&scn->x);
    scn->y1_thresh = scn->y1_min_thresh;
    if(scn->decoder)
        zebra_decoder_new_scan(scn->decoder);
    return(edge);
}
Exemplo n.º 10
0
void Graph::dfs_worker(int v, void(*process_vertex_early)(int v), 
				void(*process_vertex_late)(int v), void(*process_edge)(int v,EdgeNode *p))
{
	EdgeNode *p;
	int y;

	if(finished) return;

	discovered[v] = TRUE;

	entry_time[v] = ++time;

	process_vertex_early(v);

	p = this->edges[v];

	while(p){
		y = p->y;
		if(!discovered[y]){
			parent[y] = v;
			process_edge(v,p);
			dfs_worker(y,process_vertex_early, process_vertex_late, process_edge);
		}
		else if( (!processed[y] && parent[v] != y) || (this->directed)){
			process_edge(v,p);
		}
		if(finished) return;
		p = p->next;
	}

	process_vertex_late(v);

	exit_time[v] = ++time;

	processed[v] = TRUE;
}
void bfs(graph *g, int start)
{
    queue q;

    init_queue(&q);

    enqueue(&q, start);
    discovered[start] = true;

    while (empty_queue(&q) == false)
    {
        int v = dequeue(&q);
        process_vertex_early(v);
        processed[v] = true;

        edgenode *p = g->edges[v];
        while (p != NULL)
        {
            int y = p->y;

            if (valid_edge(p))
            {
                if ((!processed[y]) || g->directed)
                {
                    process_edge(v, y);
                }

                if (!discovered[y])
                {
                    enqueue(&q, y);
                    discovered[y] = true;
                    parent[y] = v;
                }
            }

            p = p->next;
        }

        process_vertex_late(v);
    }
}
Exemplo n.º 12
0
void dfs(Graph &g, int v)
{
    std::vector<EdgeNodePtr> nextEdge(g.vc+1);
    std::vector<VStatus> vs(g.vc+1);
    std::stack<int> s;
    
    s.push(v);
    vs[v] = DIS;
    process_vertex_early(v);
    nextEdge[v] = g.eNs[v];
    
    while (!s.empty()) {
        int x = s.top();
        
        EdgeNodePtr yp = nextEdge[x];
        
        if (yp) {
            int y = yp->y;
            nextEdge[x] = yp->next;
            
            bool newEdge = false;
            if(vs[y] == UND) {
                nextEdge[y] = g.eNs[y];
                s.push(y);
                vs[y] = DIS;
                process_vertex_early(y);

            }
            
            if (vs[y] != PRO || g.directed) {
                process_edge(x, y);
            }
        } else {
            s.pop();
            process_vertex_late(x);
            vs[x] = PRO;
        }
    }
}
Exemplo n.º 13
0
void BreadthFirstSearch::bfs(Graph *g, int start) {

    Queue q;
    int current_v;
    int successor_v;
    edgenode *current_edges;

    q.enqueue(start);
    q.print();
    discovered[start] = true;

    while(q.queueSize() > 0) {
        current_v = q.dequeue();
        process_vertex_early(current_v);
        processed[current_v] = true;

        current_edges = g->edges[current_v];

        while(current_edges != nullptr) {
           successor_v = current_edges->y;

            if((!processed[successor_v])) {
                process_edge(current_v, successor_v);
            }

            if(!discovered[successor_v]) {
                q.enqueue(successor_v);
                discovered[successor_v] = true;
                parent[successor_v] = current_v;
            }

            current_edges = current_edges->next;
        }

        process_vertex_late(current_v);
    }
}
Exemplo n.º 14
0
void dfs(struct graph *g, int node){
    struct edge *tmp = g->edges[node];
    time++;
    entry_time[node] = time;
    discovered[node] = 1;
    while(tmp){
        int y = tmp->y;
        if(!discovered[y]){
            parent[y] = node;
            process_edge(node, y);
            dfs(g, y);
        } else if(!processed[y]){
            if(parent[node] != y){
                printf("Sorry, %d -> %d this is not a DAG !\n", node, y);
            }
        }
        tmp = tmp->next;
    }
    time++;
    process_vertex_late(node);
    exit_time[node] = time;
    processed[node] = 1;
    printf("\n");
}
/*************************************************
Function:
    build_vertexes
Description:
    1. Reads sequence from *.sparse.edge.
    2. Builds vertexes by cutting the edge sequence's end kmers.
Input:
    1. v_ht:        vertex hashtable
    2. K_size:      kmer size
    3. edge_file:       edge file
Output:
    None.
Return:
    None.
*************************************************/
void build_vertexes ( vertex_hash2 * v_ht, int K_size, char * edge_file )
{
	FILE * fp;
	kmer_t2 from_kmer, to_kmer;
	size_t line_len, edge_len_left;
	int edge_len;
	int cvg;
	bool bal_ed;//回文为0
	const int BUFF_LEN = 1024;
	char line[BUFF_LEN];
	char str[32];
	char to_buff[BUFF_LEN];//buffer 2k edge seq  BUFF_LEN>4*K_size
	int processed = 0; //0表示未处理 1表示 处理完毕 2 表示已经处理了from_vertex ,to_vertex 还没有处理
	size_t edge_id = 0;
	fp = fopen ( edge_file, "r" );

	if ( !fp )
	{
		fprintf ( stderr, "ERROR: Cannot open edge_file %s. Now exit to system...\n", edge_file );
		exit ( -1 );
	}

	vertex2 * v_tmp;
	edge_starter2 * e_tmp;
	int is_found;
	bool is_left;

	while ( fgets ( line, BUFF_LEN, fp ) != NULL )
	{
		//debug<<"processed "<<processed<<endl;
		if ( line[0] == '>' ) //get one edge length, from vertex, to vertex,cvg,bal
		{
			if ( processed == 1 && bal_ed )
			{
				edge_id++;//如果不是回文
			}

#ifdef _63MER_
			sscanf ( line + 7, "%d,%llx %llx ,%llx %llx ,%s %d,%d", &edge_len,
			         & ( from_kmer.kmer ) [0], & ( from_kmer.kmer ) [1], & ( to_kmer.kmer ) [0], & ( to_kmer.kmer ) [1], str, &cvg, &bal_ed ); // from_kmer to_kmer is of no use here
#endif
#ifdef _127MER_
			sscanf ( line + 7, "%d,%llx %llx %llx %llx ,%llx %llx %llx %llx ,%s %d,%d", &edge_len,
			         & ( from_kmer.kmer ) [0], & ( from_kmer.kmer ) [1], & ( from_kmer.kmer ) [2], & ( from_kmer.kmer ) [3],
			         & ( to_kmer.kmer ) [0], & ( to_kmer.kmer ) [1], & ( to_kmer.kmer ) [2], & ( to_kmer.kmer ) [3], str, &cvg, &bal_ed ); // from_kmer to_kmer is of no use here
#endif
			edge_len_left = K_size + edge_len;
			processed = 0;
			edge_id++;// current edge positive strand id
			//debug<<line<<"edge_id "<<edge_id<<endl;
		}
		else
		{
			if ( processed == 0 )
			{
				line_len = strlen ( line );

				if ( line[line_len - 1] == '\n' )
				{
					line[line_len - 1] = '\0';
					line_len --;
				}

				if ( edge_len_left - line_len == 0 ) //edge completely loaded
				{
					//do all process
					process_edge ( v_ht, K_size, line, line_len, 1, edge_id, bal_ed );
					processed = 1;
					edge_len_left = 0;
					continue;
				}
				else  //edge partly loaded at the first time.
				{
					if ( line_len < 2 * K_size ) //line_len < 2*K_size &&edge_len_left - line_len > 0
					{
						fprintf ( stderr, "ERROR:it won't happen in 63mer/127mer\n" );
						exit ( 1 );
					}
					else
					{
						process_edge ( v_ht, K_size, line, line_len, 2, edge_id, bal_ed );
						processed = 2;
						edge_len_left -= line_len;

						if ( edge_len_left >= 2 * K_size )
						{
							//no need to buf the to kmer seq
						}
						else if ( edge_len_left < 2 * K_size )
						{
							//to_buff[100];/ copy the last 2K char of line  to to_buff  already no '\n'
							strcpy ( to_buff, line + ( line_len - 2 * K_size ) );
						}
						else
						{
							fprintf ( stderr, "ERROR: in cal the edge_len_left!!\n" );
							exit ( 1 );
						}
					}
				}
			}
			else if ( processed == 2 )
			{
				//if(line[0]=='\n') continue;
				line_len = strlen ( line );

				if ( line[line_len - 1] == '\n' )
				{
					line[line_len - 1] = '\0';
					line_len --;
				}

				edge_len_left -= line_len;

				if ( edge_len_left == 0 ) //load the complete edge sequence
				{
					//process the to kmer
					if ( line_len >= 2 * K_size )
					{
						process_edge ( v_ht, K_size, line, line_len, 3, edge_id, bal_ed );
					}
					else
					{
						//need to use the to_buff
						int buf_len = strlen ( to_buff );
						strcpy ( to_buff + buf_len, line );
						buf_len = strlen ( to_buff );
						process_edge ( v_ht, K_size, to_buff, buf_len, 3, edge_id, bal_ed );
					}

					processed = 1;
					continue;
				}
				else
				{
					if ( edge_len_left >= 2 * K_size )
					{
						//no need to buf the to kmer seq
					}
					else if ( edge_len_left < 2 * K_size )
					{
						//to_buff[100];/ copy the last 2K char of line  to to_buff
						strcpy ( to_buff, line + ( line_len - 2 * K_size ) );
					}
					else
					{
						fprintf ( stderr, "ERROR: in cal the edge_len_left!!\n" );
						exit ( 1 );
					}
				}
			}
			else
			{
				if ( line[0] == '\n' ) { continue; } //当len = 1023时

				fprintf ( stderr, "ERROR: in cal the status_processed !! %d \n", processed );
				exit ( 1 );
			}
		}
	}

	fclose ( fp );
}
Exemplo n.º 16
0
void Vectorizer::process_solution(MeshFunction* xsln, int xitem, MeshFunction* ysln, int yitem, double eps)
{
  // sanity check
  if (xsln == NULL || ysln == NULL) error("One of the solutions is NULL in Vectorizer:process_solution().");


  lock_data();
  TimePeriod cpu_time;

  // initialization
  this->xsln = xsln;
  this->ysln = ysln;
  this->xitem = xitem;
  this->yitem = yitem;
  this->eps = eps;
  nv = nt = ne = nd = 0;
  del_slot = -1;

  Mesh* meshes[2] = { xsln->get_mesh(), ysln->get_mesh() };
  if (meshes[0] == NULL || meshes[1] == NULL) {
    error("One of the meshes is NULL in Vectorizer:process_solution().");
  }

  Transformable* fns[2] = { xsln, ysln };
  Traverse trav;

  // estimate the required number of vertices and triangles
  // (based on the assumption that the linear mesh will be
  // about four-times finer than the original mesh).
  int nn = meshes[0]->get_num_elements() + meshes[1]->get_num_elements();
  int ev = std::max(32 * nn, 10000);
  int et = std::max(64 * nn, 20000);
  int ee = std::max(24 * nn, 7500);
  int ed = ee;

  lin_init_array(verts, double4, cv, ev);
  lin_init_array(tris, int3, ct, et);
  lin_init_array(edges, int3, ce, ee);
  lin_init_array(dashes, int2, cd, ed);

  info = (int4*) malloc(sizeof(int4) * cv);

  // initialize the hash table
  int size = 0x1000;
  while (size*2 < cv) size *= 2;
  hash_table = (int*) malloc(sizeof(int) * size);
  memset(hash_table, 0xff, sizeof(int) * size);
  mask = size-1;


  // select the linearization quadrature
  Quad2D *old_quad_x, *old_quad_y;
  old_quad_x = xsln->get_quad_2d();
  old_quad_y = ysln->get_quad_2d();

  xsln->set_quad_2d((Quad2D*) &quad_lin);
  ysln->set_quad_2d((Quad2D*) &quad_lin);

  if (!xitem) error("Parameter 'xitem' cannot be zero.");
  if (!yitem) error("Parameter 'yitem' cannot be zero.");
  get_gv_a_b(xitem, xia, xib);
  get_gv_a_b(yitem, yia, yib);
  if (xib >= 6) error("Invalid value of paremeter 'xitem'.");
  if (yib >= 6) error("Invalid value of paremeter 'yitem'.");

  max = 1e-10;
  trav.begin(2, meshes, fns);
  Element** e;
  while ((e = trav.get_next_state(NULL, NULL)) != NULL)
  {
    xsln->set_quad_order(0, xitem);
    ysln->set_quad_order(0, yitem);
    scalar* xval = xsln->get_values(xia, xib);
    scalar* yval = ysln->get_values(yia, yib);

    for (unsigned int i = 0; i < e[0]->nvert; i++)
    {
      double fx = getvalx(i);
      double fy = getvaly(i);
      if (fabs(sqrt(fx*fx + fy*fy)) > max) max = fabs(sqrt(fx*fx + fy*fy));
    }
  }
  trav.finish();

  trav.begin(2, meshes, fns);
  // process all elements of the mesh
  while ((e = trav.get_next_state(NULL, NULL)) != NULL)
  {
    xsln->set_quad_order(0, xitem);
    ysln->set_quad_order(0, yitem);
    scalar* xval = xsln->get_values(xia, xib);
    scalar* yval = ysln->get_values(yia, yib);

    double* x = xsln->get_refmap()->get_phys_x(0);
    double* y = ysln->get_refmap()->get_phys_y(0);

    int iv[4];
    for (unsigned int i = 0; i < e[0]->nvert; i++)
    {
      double fx = getvalx(i);
      double fy = getvaly(i);
      iv[i] = create_vertex(x[i], y[i], fx, fy);
    }

    // we won't bother calculating physical coordinates from the refmap if this is not a curved element
    curved = (e[0]->cm != NULL);

    // recur to sub-elements
    if (e[0]->is_triangle())
      process_triangle(iv[0], iv[1], iv[2], 0, NULL, NULL, NULL, NULL, NULL);
    else
      process_quad(iv[0], iv[1], iv[2], iv[3], 0, NULL, NULL, NULL, NULL, NULL);

    // process edges and dashes (bold line for edge in both meshes, dashed line for edge in one of the meshes)
    Trf* xctm = xsln->get_ctm();
    Trf* yctm = ysln->get_ctm();
    double r[4] = { -1.0, 1.0, 1.0, -1.0 };
    double ref[4][2] = { {-1.0,-1.0}, {1.0,-1.0}, {1.0,1.0}, {-1.0,1.0} };
    for (unsigned int i = 0; i < e[0]->nvert; i++)
    {
      bool bold = false;
      double px = ref[i][0];
      double py = ref[i][1];
      // for odd edges (1, 3) we check x coordinate after ctm transformation, if it's the same (1 or -1) in both meshes => bold
      if (i & 1) {
        if ((xctm->m[0]*px + xctm->t[0] == r[i]) && (yctm->m[0]*px + yctm->t[0] == r[i]))
          bold = true;
      }
      // for even edges (0, 4) we check y coordinate after ctm transformation, if it's the same (-1 or 1) in both meshes => bold
      else {
        if ((xctm->m[1]*py + xctm->t[1] == r[i]) && (yctm->m[1]*py + yctm->t[1] == r[i]))
          bold = true;
      }
      int j = e[0]->next_vert(i);
      // we draw a line only if both edges lies on the boundary or if the line is from left top to right bottom
      if (((e[0]->en[i]->bnd) && (e[1]->en[i]->bnd)) ||
         (verts[iv[i]][1] < verts[iv[j]][1]) ||
         (verts[iv[i]][1] == verts[iv[j]][1] && verts[iv[i]][0] < verts[iv[j]][0]))
      {
        if (bold)
          process_edge(iv[i], iv[j], e[0]->en[i]->marker);
        else
          process_dash(iv[i], iv[j]);
      }
    }
  }
  trav.finish();

  find_min_max();

  verbose("Vectorizer created %d verts and %d tris in %0.3g s", nv, nt, cpu_time.tick().last());
  //if (verbose_mode) print_hash_stats();
  unlock_data();

   // select old quadratrues
  xsln->set_quad_2d(old_quad_x);
  ysln->set_quad_2d(old_quad_y);

  // clean up
  ::free(hash_table);
  ::free(info);

}
Exemplo n.º 17
0
//**********************************************************************************
// function: rr_active_sites
//
// description: Determines if request_router has acvive edge sites.
//              Returns 0 for no sites, # of active edge sites.
//**********************************************************************************
static int16_t rr_active_sites(tc_health_thread_ctxt_t * pCntx,
                               const char * ip)
{
    CURL * curl;
    CURLcode res;
    UrlData_t url_data;
    json_error_t error;
    int16_t ret = 0;
    const char * url_fmt = "http://%s/api/servers/";
    char url[64];

    bzero(&url_data, sizeof(url_data));
    snprintf(url, sizeof(url),url_fmt, ip);
    url[sizeof(url)-1] = '\0';
 
    curl = curl_easy_init();
    if(NULL == curl)
        return 0;
    curl_easy_setopt(curl, CURLOPT_URL, url);
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, UrlCallback);
    curl_easy_setopt(curl, CURLOPT_NOSIGNAL,1L);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)& url_data);
    curl_easy_setopt(curl, CURLOPT_USERAGENT, "libcurl-agent/1.0");
 
    res = curl_easy_perform(curl);
    if(res != CURLE_OK)
    {
        curl_easy_cleanup(curl);
        return 0;
    }
    curl_easy_cleanup(curl);

    json_t * root = json_loads(url_data.buffer, 0, &error);
    if(!root)
        return 0;
    void *iter = json_object_iter(root);
    if(!iter)
    {
        json_decref(root);
        return 0;
    }
    const char * key = json_object_iter_key(iter);
    json_t * j = json_object_iter_value(iter);

    json_object_del(j, "route_expression");
    json_object_del(j, "route_expression_suffix");
    json_object_del(j, "date");
    json_object_del(j, "active_sites");
    json_object_del(j, "supported_sites");

    json_t * edge_cluster;
    json_object_foreach(j, key, edge_cluster)
    {
        evLogTrace(
                pCntx->pQHealthToBkgrnd,
                evLogLvlDebug,
                &(pCntx->tLogDescSys),
                "Processing edge_cluster %s.", key);
        void *iter = json_object_iter(edge_cluster);
        if(process_edge(json_object_iter_value(iter)))
        {
            ret = 1;
            break;
        }
    }
int CHOLMOD(rowcolcounts)
(
    /* ---- input ---- */
    cholmod_sparse *A,	/* matrix to analyze */
    Int *fset,		/* subset of 0:(A->ncol)-1 */
    size_t fsize,	/* size of fset */
    Int *Parent,	/* size nrow.  Parent [i] = p if p is the parent of i */
    Int *Post,		/* size nrow.  Post [k] = i if i is the kth node in
			 * the postordered etree. */
    /* ---- output --- */
    Int *RowCount,	/* size nrow. RowCount [i] = # entries in the ith row of
			 * L, including the diagonal. */
    Int *ColCount,	/* size nrow. ColCount [i] = # entries in the ith
			 * column of L, including the diagonal. */
    Int *First,		/* size nrow.  First [i] = k is the least postordering
			 * of any descendant of i. */
    Int *Level,		/* size nrow.  Level [i] is the length of the path from
			 * i to the root, with Level [root] = 0. */
    /* --------------- */
    cholmod_common *Common
)
{
    double fl, ff ;
    Int *Ap, *Ai, *Anz, *PrevNbr, *SetParent, *Head, *PrevLeaf, *Anext, *Ipost,
	*Iwork ;
    Int i, j, r, k, len, s, p, pend, inew, stype, nf, anz, inode, parent,
	nrow, ncol, packed, use_fset, jj ;
    size_t w ;
    int ok = TRUE ;

    /* ---------------------------------------------------------------------- */
    /* check inputs */
    /* ---------------------------------------------------------------------- */

    RETURN_IF_NULL_COMMON (FALSE) ;
    RETURN_IF_NULL (A, FALSE) ;
    RETURN_IF_NULL (Parent, FALSE) ;
    RETURN_IF_NULL (Post, FALSE) ;
    RETURN_IF_NULL (ColCount, FALSE) ;
    RETURN_IF_NULL (First, FALSE) ;
    RETURN_IF_NULL (Level, FALSE) ;
    RETURN_IF_XTYPE_INVALID (A, CHOLMOD_PATTERN, CHOLMOD_ZOMPLEX, FALSE) ;
    stype = A->stype ;
    if (stype > 0)
    {
	/* symmetric with upper triangular part not supported */
	ERROR (CHOLMOD_INVALID, "symmetric upper not supported") ;
	return (FALSE) ;
    }
    Common->status = CHOLMOD_OK ;

    /* ---------------------------------------------------------------------- */
    /* allocate workspace */
    /* ---------------------------------------------------------------------- */

    nrow = A->nrow ;	/* the number of rows of A */
    ncol = A->ncol ;	/* the number of columns of A */

    /* w = 2*nrow + (stype ? 0 : ncol) */
    w = CHOLMOD(mult_size_t) (nrow, 2, &ok) ;
    w = CHOLMOD(add_size_t) (w, (stype ? 0 : ncol), &ok) ;
    if (!ok)
    {
	ERROR (CHOLMOD_TOO_LARGE, "problem too large") ;
	return (FALSE) ;
    }

    CHOLMOD(allocate_work) (nrow, w, 0, Common) ;
    if (Common->status < CHOLMOD_OK)
    {
	return (FALSE) ;
    }

    ASSERT (CHOLMOD(dump_perm) (Post, nrow, nrow, "Post", Common)) ;
    ASSERT (CHOLMOD(dump_parent) (Parent, nrow, "Parent", Common)) ;

    /* ---------------------------------------------------------------------- */
    /* get inputs */
    /* ---------------------------------------------------------------------- */

    Ap = A->p ;	/* size ncol+1, column pointers for A */
    Ai = A->i ;	/* the row indices of A, of size nz=Ap[ncol+1] */
    Anz = A->nz ;
    packed = A->packed ;
    ASSERT (IMPLIES (!packed, Anz != NULL)) ;

    /* ---------------------------------------------------------------------- */
    /* get workspace */
    /* ---------------------------------------------------------------------- */

    Iwork = Common->Iwork ;
    SetParent = Iwork ;		    /* size nrow (i/i/l) */
    PrevNbr   = Iwork + nrow ;	    /* size nrow (i/i/l) */
    Anext     = Iwork + 2*((size_t) nrow) ;    /* size ncol (i/i/l) (unsym only) */
    PrevLeaf  = Common->Flag ;	    /* size nrow */
    Head      = Common->Head ;	    /* size nrow+1 (unsym only)*/

    /* ---------------------------------------------------------------------- */
    /* find the first descendant and level of each node in the tree */
    /* ---------------------------------------------------------------------- */

    /* First [i] = k if the postordering of first descendent of node i is k */
    /* Level [i] = length of path from node i to the root (Level [root] = 0) */

    for (i = 0 ; i < nrow ; i++)
    {
	First [i] = EMPTY ;
    }

    /* postorder traversal of the etree */
    for (k = 0 ; k < nrow ; k++)
    {
	/* node i of the etree is the kth node in the postordered etree */
	i = Post [k] ;

	/* i is a leaf if First [i] is still EMPTY */
	/* ColCount [i] starts at 1 if i is a leaf, zero otherwise */
	ColCount [i] = (First [i] == EMPTY) ? 1 : 0 ;

	/* traverse the path from node i to the root, stopping if we find a
	 * node r whose First [r] is already defined. */
	len = 0 ;
	for (r = i ; (r != EMPTY) && (First [r] == EMPTY) ; r = Parent [r])
	{
	    First [r] = k ;
	    len++ ;
	}
	if (r == EMPTY)
	{
	    /* we hit a root node, the level of which is zero */
	    len-- ;
	}
	else
	{
	    /* we stopped at node r, where Level [r] is already defined */
	    len += Level [r] ;
	}
	/* re-traverse the path from node i to r; set the level of each node */
	for (s = i ; s != r ; s = Parent [s])
	{
	    Level [s] = len-- ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* AA' case: sort columns of A according to first postordered row index */
    /* ---------------------------------------------------------------------- */

    fl = 0.0 ;
    if (stype == 0)
    {
	/* [ use PrevNbr [0..nrow-1] as workspace for Ipost */
	Ipost = PrevNbr ;
	/* Ipost [i] = k if i is the kth node in the postordered etree. */
	for (k = 0 ; k < nrow ; k++)
	{
	    Ipost [Post [k]] = k ;
	}
	use_fset = (fset != NULL) ;
	if (use_fset)
	{
	    nf = fsize ;
	    /* clear Anext to check fset */
	    for (j = 0 ; j < ncol ; j++)
	    {
		Anext [j] = -2 ;
	    }
	    /* find the first postordered row in each column of A (post,f)
	     * and place the column in the corresponding link list */
	    for (jj = 0 ; jj < nf ; jj++)
	    {
		j = fset [jj] ;
		if (j < 0 || j > ncol || Anext [j] != -2)
		{
		    /* out-of-range or duplicate entry in fset */
		    ERROR (CHOLMOD_INVALID, "fset invalid") ;
		    return (FALSE) ;
		}
		/* flag column j as having been seen */
		Anext [j] = EMPTY ;
	    }
	    /* fset is now valid */
	    ASSERT (CHOLMOD(dump_perm) (fset, nf, ncol, "fset", Common)) ;
	}
	else
	{
	    nf = ncol ;
	}
	for (jj = 0 ; jj < nf ; jj++)
	{
	    j = (use_fset) ? (fset [jj]) : jj ;
	    /* column j is in the fset; find the smallest row (if any) */
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    ff = (double) MAX (0, pend - p) ;
	    fl += ff*ff + ff ;
	    if (pend > p)
	    {
		k = Ipost [Ai [p]] ;
		for ( ; p < pend ; p++)
		{
		    inew = Ipost [Ai [p]] ;
		    k = MIN (k, inew) ;
		}
		/* place column j in link list k */
		ASSERT (k >= 0 && k < nrow) ;
		Anext [j] = Head [k] ;
		Head [k] = j ;
	    }
	}
	/* Ipost no longer needed for inverse postordering ]
	 * Head [k] contains a link list of all columns whose first
	 * postordered row index is equal to k, for k = 0 to nrow-1. */
    }

    /* ---------------------------------------------------------------------- */
    /* compute the row counts and node weights */
    /* ---------------------------------------------------------------------- */

    if (RowCount != NULL)
    {
	for (i = 0 ; i < nrow ; i++)
	{
	    RowCount [i] = 1 ;
	}
    }
    for (i = 0 ; i < nrow ; i++)
    {
	PrevLeaf [i] = EMPTY ;
	PrevNbr [i] = EMPTY ;
	SetParent [i] = i ;	/* every node is in its own set, by itself */
    }

    if (stype != 0)
    {

	/* ------------------------------------------------------------------ */
	/* symmetric case: LL' = A */
	/* ------------------------------------------------------------------ */

	/* also determine the number of entries in triu(A) */
	anz = nrow ;
	for (k = 0 ; k < nrow ; k++)
	{
	    /* j is the kth node in the postordered etree */
	    j = initialize_node (k, Post, Parent, ColCount, PrevNbr) ;

	    /* for all nonzeros A(i,j) below the diagonal, in column j of A */
	    p = Ap [j] ;
	    pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
	    for ( ; p < pend ; p++)
	    {
		i = Ai [p] ;
		if (i > j)
		{
		    /* j is a descendant of i in etree(A) */
		    anz++ ;
		    process_edge (j, i, k, First, PrevNbr, ColCount,
			    PrevLeaf, RowCount, SetParent, Level) ;
		}
	    }
	    /* update SetParent: UNION (j, Parent [j]) */
	    finalize_node (j, Parent, SetParent) ;
	}
	Common->anz = anz ;
    }
    else
    {

	/* ------------------------------------------------------------------ */
	/* unsymmetric case: LL' = AA' */
	/* ------------------------------------------------------------------ */

	for (k = 0 ; k < nrow ; k++)
	{
	    /* inode is the kth node in the postordered etree */
	    inode = initialize_node (k, Post, Parent, ColCount, PrevNbr) ;

	    /* for all cols j whose first postordered row is k: */
	    for (j = Head [k] ; j != EMPTY ; j = Anext [j])
	    {
		/* k is the first postordered row in column j of A */
		/* for all rows i in column j: */
		p = Ap [j] ;
		pend = (packed) ? (Ap [j+1]) : (p + Anz [j]) ;
		for ( ; p < pend ; p++)
		{
		    i = Ai [p] ;
		    /* has i already been considered at this step k */
		    if (PrevNbr [i] < k)
		    {
			/* inode is a descendant of i in etree(AA') */
			/* process edge (inode,i) and set PrevNbr[i] to k */
			process_edge (inode, i, k, First, PrevNbr, ColCount,
				PrevLeaf, RowCount, SetParent, Level) ;
		    }
		}
	    }
	    /* clear link list k */
	    Head [k] = EMPTY ;
	    /* update SetParent: UNION (inode, Parent [inode]) */
	    finalize_node (inode, Parent, SetParent) ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* finish computing the column counts */
    /* ---------------------------------------------------------------------- */

    for (j = 0 ; j < nrow ; j++)
    {
	parent = Parent [j] ;
	if (parent != EMPTY)
	{
	    /* add the ColCount of j to its parent */
	    ColCount [parent] += ColCount [j] ;
	}
    }

    /* ---------------------------------------------------------------------- */
    /* clear workspace */
    /* ---------------------------------------------------------------------- */

    Common->mark = EMPTY ;
    /* CHOLMOD(clear_flag) (Common) ; */
    CHOLMOD_CLEAR_FLAG (Common) ;

    ASSERT (CHOLMOD(dump_work) (TRUE, TRUE, 0, Common)) ;

    /* ---------------------------------------------------------------------- */
    /* flop count and nnz(L) for subsequent LL' numerical factorization */
    /* ---------------------------------------------------------------------- */

    /* use double to avoid integer overflow.  lnz cannot be NaN. */
    Common->aatfl = fl ;
    Common->lnz = 0. ;
    fl = 0 ;
    for (j = 0 ; j < nrow ; j++)
    {
	ff = (double) (ColCount [j]) ;
	Common->lnz += ff ;
	fl += ff*ff ;
    }

    Common->fl = fl ;
    PRINT1 (("rowcol fl %g lnz %g\n", Common->fl, Common->lnz)) ;

    return (TRUE) ;
}