From: Peter Stamfest Date: Thu, 14 Aug 2014 07:05:04 +0000 (+0200) Subject: Keep a pointer to the internal rrd data structure with rrd_file_t objects X-Git-Tag: v1.5.0-rc1~42^2~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=669b483722a63a902f57d562a54cbfc1c3d38d36;p=thirdparty%2Frrdtool-1.x.git Keep a pointer to the internal rrd data structure with rrd_file_t objects to simplify management of opened RRD files - now it is only required to keep the rrd_file_t object around to be able to manage the underlying rrd structure and not both objects in some additional data structure. --- diff --git a/src/rrd.h b/src/rrd.h index 6156475d..5eb52355 100644 --- a/src/rrd.h +++ b/src/rrd.h @@ -75,6 +75,10 @@ extern "C" { #ifndef DNAN # define DNAN rrd_set_to_DNAN() #endif + +/* declare opaque data structure, so we can use its pointers for type safety */ + +struct rrd_t; #ifndef DINF # define DINF rrd_set_to_DINF() @@ -96,6 +100,7 @@ extern "C" { size_t file_len; /* total size of the rrd file */ size_t pos; /* current pos in file */ void *pvt; + struct rrd_t *rrd; /* the corresponding RRD structure, if any */ } rrd_file_t; /* information used for the conventional file access methods */ diff --git a/src/rrd_create.c b/src/rrd_create.c index 93ee0b04..2768c28f 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -28,6 +28,7 @@ #endif static int rrd_init_data(rrd_t *rrd); +static int rrd_prefill_data(rrd_t *rrd, const GList *sources_rrd_files); unsigned long FnvHash( const char *str); @@ -574,6 +575,20 @@ int rrd_create_r( { return rrd_create_r2(filename,pdp_step,last_up,0, NULL, argc,argv); } + + +static void cleanup_source_file(rrd_file_t *file) { + if (file == NULL) return; + + if (file->rrd != NULL) { + rrd_free(file->rrd); + free(file->rrd); + file->rrd = NULL; + } + + rrd_close(file); +} + int rrd_create_r2( const char *filename, unsigned long pdp_step, @@ -588,6 +603,7 @@ int rrd_create_r2( unsigned long hashed_name; int rc = -1; struct stat stat_buf; + GList *sources_rrd_files = NULL; /* clear any previous errors */ rrd_clear_error(); @@ -703,9 +719,35 @@ int rrd_create_r2( rc = rrd_init_data(&rrd); if (rc != 0) goto done; + if (sources != NULL) { + for (const char **s = sources ; *s ; s++) { + rrd_t *srrd = malloc(sizeof(rrd_t)); + if (srrd == NULL) { + rrd_set_error("cannot allocate memory"); + goto done; + } + + rrd_init(srrd); + rrd_file_t *sf = rrd_open(*s, srrd, RRD_READAHEAD | RRD_READVALUES); + + if (sf == NULL) { + goto done; + } + sources_rrd_files = g_list_append(sources_rrd_files, sf); + if (sources_rrd_files == NULL) { + rrd_set_error("Cannot keep information about just opened source RRD - likely leaking resources!"); + goto done; + } + } + + rrd_prefill_data(&rrd, sources_rrd_files); + } + rc = write_rrd(filename, &rrd); done: + g_list_free_full(sources_rrd_files, (GDestroyNotify) cleanup_source_file); + rrd_free(&rrd); return rc; } @@ -1129,3 +1171,17 @@ int write_fh( return (0); } /* int write_file */ +static int rrd_prefill_data(rrd_t *rrd, const GList *sources) { + /* for each DS in each RRA within rrd find a list of candidate DS/RRAs from + * the sources list that match by name... */ + + + /* within each source file, order the RRAs by resolution - if we have an + * exact resolution match, use that one as the first in the (sub)list. */ + + /* for each bin in each RRA select the best bin from among the candidate + * RRA data sets */ + + return 0; +} + diff --git a/src/rrd_open.c b/src/rrd_open.c index 63e56224..e7b781c0 100644 --- a/src/rrd_open.c +++ b/src/rrd_open.c @@ -131,7 +131,8 @@ rrd_file_t *rrd_open( return NULL; } memset(rrd_file, 0, sizeof(rrd_file_t)); - + rrd_file->rrd = rrd; + rrd_file->pvt = malloc(sizeof(rrd_simple_file_t)); if(rrd_file->pvt == NULL) { rrd_set_error("allocating rrd_simple_file for '%s'", file_name);