From 714065a843364feadfc17f5275ee070de4cbc656 Mon Sep 17 00:00:00 2001 From: alexgutteridge Date: Sun, 5 Aug 2007 07:14:34 +0000 Subject: [PATCH] New attribute handling. git-svn-id: http://igraph.rubyforge.org/svn/trunk@21 71f48855-0bbf-4aa5-930d-4df415e86613 --- ext/cIGraph.c | 20 +++---- ext/cIGraph_add_delete.c | 121 +++++++++++++++++---------------------- ext/cIGraph_selectors.c | 2 +- ext/cIGraph_utility.c | 45 +++++++-------- 4 files changed, 83 insertions(+), 105 deletions(-) diff --git a/ext/cIGraph.c b/ext/cIGraph.c index f5cdf2a..6f6656b 100644 --- a/ext/cIGraph.c +++ b/ext/cIGraph.c @@ -58,10 +58,11 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ int i; igraph_vector_ptr_t vertex_attr; + igraph_vector_ptr_t edge_attr; rb_scan_args(argc,argv,"12", &edges, &directed, &attrs); - igraph_set_error_handler(cIGraph_error_handler); + igraph_set_error_handler(cIGraph_error_handler); igraph_set_warning_handler(cIGraph_warning_handler); //New hash for mapping vertex objects to floats used by iGraph @@ -72,7 +73,9 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ //Initialize edge vector igraph_vector_init_int(&edge_v,0); + igraph_vector_ptr_init(&vertex_attr,0); + igraph_vector_ptr_init(&edge_attr,0); Data_Get_Struct(self, igraph_t, graph); @@ -97,24 +100,19 @@ VALUE cIGraph_initialize(int argc, VALUE *argv, VALUE self){ } igraph_vector_push_back(&edge_v,current_vertex_id); + if (attrs != Qnil && i % 2){ + igraph_vector_ptr_push_back(&edge_attr,(void*)RARRAY(attrs)->ptr[i/2]); + } } if(igraph_vector_size(&edge_v) > 0){ igraph_add_vertices(graph,vertex_n,&vertex_attr); - igraph_add_edges(graph,&edge_v,0); + igraph_add_edges(graph,&edge_v,&edge_attr); } - //if(attrs != Qnil){ - //for (i=0; ilen; i++) { - // cIGraph_set_edge_attr(self, - // RARRAY(edges)->ptr[i*2], - // RARRAY(edges)->ptr[(i*2)+1], - // RARRAY(attrs)->ptr[i]); - //} - //} - igraph_vector_destroy(&edge_v); igraph_vector_ptr_destroy(&vertex_attr); + igraph_vector_ptr_destroy(&edge_attr); return self; diff --git a/ext/cIGraph_add_delete.c b/ext/cIGraph_add_delete.c index c13eda0..b1ce2af 100644 --- a/ext/cIGraph_add_delete.c +++ b/ext/cIGraph_add_delete.c @@ -24,47 +24,44 @@ VALUE cIGraph_add_edges(int argc, VALUE *argv, VALUE self){ igraph_t *graph; igraph_vector_t edge_v; VALUE vertex; - VALUE object_h; VALUE edges; VALUE attrs; + VALUE v_ary; int vid; int code = 0; int i; + igraph_vector_ptr_t edge_attr; rb_scan_args(argc, argv, "11", &edges, &attrs); //Initialize edge vector igraph_vector_init_int(&edge_v,0); - object_h = rb_iv_get(self,"@object_ids"); + igraph_vector_ptr_init(&edge_attr,0); Data_Get_Struct(self, igraph_t, graph); + v_ary = ((VALUE*)graph->attr)[0]; + //Loop through objects in edge Array for (i=0; ilen; i++) { vertex = RARRAY(edges)->ptr[i]; - if(rb_funcall(object_h,rb_intern("has_key?"),1,vertex)){ - //If @vertices includes this vertex then look up the vertex number - vid = NUM2INT(rb_hash_aref(object_h,vertex)); + if(rb_ary_includes(v_ary,vertex)){ + vid = cIGraph_get_vertex_id(self, vertex); } else { rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); } igraph_vector_push_back(&edge_v,vid); + if (attrs != Qnil && i % 2){ + igraph_vector_ptr_push_back(&edge_attr,(void*)RARRAY(attrs)->ptr[i/2]); + } } if(igraph_vector_size(&edge_v) > 0){ - code = igraph_add_edges(graph,&edge_v,0); + code = igraph_add_edges(graph,&edge_v,&edge_attr); } - //if(attrs != Qnil){ - // for (i=0; ilen; i++) { - // cIGraph_set_edge_attr(self, - // RARRAY(edges)->ptr[i*2], - // RARRAY(edges)->ptr[(i*2)+1], - // RARRAY(attrs)->ptr[i]); -//} - //} - igraph_vector_destroy(&edge_v); + igraph_vector_ptr_destroy(&edge_attr); return INT2NUM(code); @@ -89,36 +86,32 @@ VALUE cIGraph_add_vertices(VALUE self, VALUE vs){ igraph_t *graph; VALUE vertex; - VALUE object_h; - VALUE id_h; - int vertex_n; + VALUE v_ary; int code = 0; - int length; + int to_add; int i; + igraph_vector_ptr_t vertex_attr; - object_h = rb_iv_get(self,"@object_ids"); - id_h = rb_iv_get(self,"@id_objects"); - length = NUM2INT(rb_funcall(vs, rb_intern("length"),0)); - vertex_n = NUM2INT(rb_funcall(object_h,rb_intern("length"),0)); + igraph_vector_ptr_init(&vertex_attr,0); Data_Get_Struct(self, igraph_t, graph); + v_ary = ((VALUE*)graph->attr)[0]; + + to_add = RARRAY(vs)->len; //Loop through objects in vertex array for (i=0; ilen; i++) { vertex = RARRAY(vs)->ptr[i]; - if(rb_funcall(object_h,rb_intern("has_key?"),1,vertex)){ - //If @vertices includes this vertex then raise an error - //Silently ignore + if(rb_ary_includes(v_ary,vertex)){ + //Silently ignore duplicated additions //rb_raise(cIGraphError, "Vertex already added to graph"); - length--; + to_add--; } else { - //otherwise add a new entry to Hash - rb_hash_aset(object_h,vertex,INT2NUM(vertex_n)); - rb_hash_aset(id_h, INT2NUM(vertex_n),vertex); - vertex_n++; + igraph_vector_ptr_push_back(&vertex_attr,(void*)RARRAY(vs)->ptr[i]); } } - code = igraph_add_vertices(graph,length,0); + + code = igraph_add_vertices(graph,to_add,&vertex_attr); return INT2NUM(code); @@ -144,9 +137,11 @@ VALUE cIGraph_add_edge(int argc, VALUE *argv, VALUE self){ igraph_t *graph; igraph_vector_t edge_v; - VALUE object_h; - int vid; + igraph_vector_ptr_t edge_attr; + int code = 0; + + VALUE v_ary; VALUE from; VALUE to; VALUE attr; @@ -155,32 +150,29 @@ VALUE cIGraph_add_edge(int argc, VALUE *argv, VALUE self){ //Initialize edge vector igraph_vector_init_int(&edge_v,0); - object_h = rb_iv_get(self,"@object_ids"); + igraph_vector_ptr_init(&edge_attr,0); Data_Get_Struct(self, igraph_t, graph); - if(rb_funcall(object_h,rb_intern("has_key?"),1,from)){ - //If @vertices includes this vertex then look up the vertex number - vid = NUM2INT(rb_hash_aref(object_h,from)); - } else { - rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); - } - igraph_vector_push_back(&edge_v,vid); + v_ary = ((VALUE*)graph->attr)[0]; - if(rb_funcall(object_h,rb_intern("has_key?"),1,to)){ - //If @vertices includes this vertex then look up the vertex number - vid = NUM2INT(rb_hash_aref(object_h,to)); + if(rb_ary_includes(v_ary,from) && rb_ary_includes(v_ary,to)){ + //If graph includes this vertex then look up the vertex number + igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, from)); + igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, to)); + if (attr != Qnil){ + igraph_vector_ptr_push_back(&edge_attr,(void*)attr); + } } else { rb_raise(cIGraphError, "Unknown vertex in edge array. Use add_vertices first"); } - igraph_vector_push_back(&edge_v,vid); - code = igraph_add_edges(graph,&edge_v,0); + igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, from)); + igraph_vector_push_back(&edge_v,cIGraph_get_vertex_id(self, to)); - if(attr != Qnil){ - //cIGraph_set_edge_attr(self, from, to, attr); - } + code = igraph_add_edges(graph,&edge_v,&edge_attr); + igraph_vector_ptr_destroy(&edge_attr); igraph_vector_destroy(&edge_v); return INT2NUM(code); @@ -206,34 +198,27 @@ VALUE cIGraph_add_edge(int argc, VALUE *argv, VALUE self){ VALUE cIGraph_add_vertex(VALUE self, VALUE v){ igraph_t *graph; - VALUE object_h; - VALUE id_h; - int vertex_n; + igraph_vector_ptr_t vertex_attr; + int code = 0; - int length; - object_h = rb_iv_get(self,"@object_ids"); - id_h = rb_iv_get(self,"@id_objects"); - length = 1; - vertex_n = NUM2INT(rb_funcall(object_h,rb_intern("length"),0)); + VALUE v_ary; + + igraph_vector_ptr_init(&vertex_attr,0); Data_Get_Struct(self, igraph_t, graph); + v_ary = ((VALUE*)graph->attr)[0]; + //Loop through objects in vertex array - if(rb_funcall(object_h,rb_intern("has_key?"),1,v)){ - //If @vertices includes this vertex then raise an error - //Silently ignore + if(rb_ary_includes(v_ary,v)){ //rb_raise(cIGraphError, "Vertex already added to graph"); - length--; + return code; } else { - //otherwise add a new entry to Hash - rb_hash_aset(object_h,v,INT2NUM(vertex_n)); - rb_hash_aset(id_h, INT2NUM(vertex_n),v); - vertex_n++; + igraph_vector_ptr_push_back(&vertex_attr,(void*)v); } - if(length != 0) - code = igraph_add_vertices(graph,length,0); + code = igraph_add_vertices(graph,1,&vertex_attr); return INT2NUM(code); diff --git a/ext/cIGraph_selectors.c b/ext/cIGraph_selectors.c index 12d4d1c..95014f4 100644 --- a/ext/cIGraph_selectors.c +++ b/ext/cIGraph_selectors.c @@ -18,7 +18,7 @@ VALUE cIGraph_all_v(VALUE self){ igraph_t *graph; Data_Get_Struct(self, igraph_t, graph); - return rb_funcall(rb_iv_get(self,"@object_ids"),rb_intern("keys"),0); + return ((VALUE*)graph->attr)[0]; } diff --git a/ext/cIGraph_utility.c b/ext/cIGraph_utility.c index 0675c93..2117d54 100644 --- a/ext/cIGraph_utility.c +++ b/ext/cIGraph_utility.c @@ -4,14 +4,17 @@ igraph_integer_t cIGraph_get_vertex_id(VALUE graph, VALUE v){ - //VALUE vertex_h; + VALUE v_ary; + VALUE idx; + igraph_t *igraph; - //vertex_h = rb_iv_get(graph,"@object_ids"); + Data_Get_Struct(graph, igraph_t, igraph); + v_ary = ((VALUE*)igraph->attr)[0]; - VALUE vertex_array = ((VALUE*)graph->attr)[0]; + idx = rb_funcall(v_ary,rb_intern("index"),1,v); - if(rb_funcall(vertex_h,rb_intern("has_key?"),1,v)) - return NUM2INT(rb_hash_aref(vertex_h,v)); + if(idx) + return NUM2INT(idx); return -1; @@ -19,14 +22,16 @@ igraph_integer_t cIGraph_get_vertex_id(VALUE graph, VALUE v){ VALUE cIGraph_get_vertex_object(VALUE graph, igraph_integer_t n){ - VALUE vertex_h; + VALUE v_ary; + VALUE obj; + igraph_t *igraph; - vertex_h = rb_iv_get(graph,"@id_objects"); + Data_Get_Struct(graph, igraph_t, igraph); + v_ary = ((VALUE*)igraph->attr)[0]; - if(rb_funcall(vertex_h,rb_intern("has_key?"),1,INT2NUM(n))) - return rb_hash_aref(vertex_h,INT2NUM(n)); + obj = rb_ary_entry(graph,n); - return Qnil; + return obj; } @@ -53,22 +58,12 @@ int cIGraph_vertex_arr_to_id_vec(VALUE graph, VALUE va, igraph_vector_t *nv){ } VALUE cIGraph_include(VALUE self, VALUE v){ - VALUE vertex_h = rb_iv_get(self,"@object_ids"); - return rb_funcall(vertex_h,rb_intern("has_key?"),1,v); -} - -VALUE cIGraph_create_derived_graph(VALUE old_graph, igraph_t *new_graph){ - - VALUE new_graph_obj; - - //Wrap new graph object - new_graph_obj = Data_Wrap_Struct(cIGraph, 0, cIGraph_free, new_graph); - //Go through hashes of old graph and copy across - //are vertex ids the same? If not we're bolloxed - rb_iv_set(new_graph_obj,"@object_ids",rb_iv_get(old_graph,"@object_ids")); - rb_iv_set(new_graph_obj,"@id_objects",rb_iv_get(old_graph,"@id_objects")); + VALUE v_ary; + igraph_t *igraph; - return new_graph_obj; + Data_Get_Struct(self, igraph_t, igraph); + v_ary = ((VALUE*)igraph->attr)[0]; + return rb_ary_includes(v_ary,v); }