/* * This function is called when creating a new RRD * The storage implementation can use this opportunity to select * a sensible starting row within the file. * The default implementation is random, to ensure that all RRAs * don't change to a new disk block at the same time */ unsigned long rrd_select_initial_row( rrd_file_t UNUSED(*rrd_file), int UNUSED(rra_idx), rra_def_t *rra ) { return rrd_random() % rra->row_cnt; }
static int parse_tag_rra_database( xmlTextReaderPtr reader, rrd_t *rrd ) { rra_def_t *cur_rra_def; rra_ptr_t *cur_rra_ptr; unsigned int total_row_cnt; int status; int i; xmlChar *element; unsigned int start_row_cnt; int ds_cnt; ds_cnt = rrd->stat_head->ds_cnt; total_row_cnt = 0; for (i = 0; i < (((int) rrd->stat_head->rra_cnt) - 1); i++) total_row_cnt += rrd->rra_def[i].row_cnt; cur_rra_def = rrd->rra_def + i; cur_rra_ptr = rrd->rra_ptr + i; start_row_cnt = total_row_cnt; status = 0; while ((element = get_xml_element(reader)) != NULL){ if (xmlStrcasecmp(element,(const xmlChar *)"row") == 0){ rrd_value_t *temp; rrd_value_t *cur_rrd_value; unsigned int total_values_count = rrd->stat_head->ds_cnt * (total_row_cnt + 1); /* Allocate space for the new values.. */ temp = (rrd_value_t *) realloc(rrd->rrd_value, sizeof(rrd_value_t) * total_values_count); if (temp == NULL) { rrd_set_error("parse_tag_rra_database: realloc failed."); status = -1; break; } rrd->rrd_value = temp; cur_rrd_value = rrd->rrd_value + (rrd->stat_head->ds_cnt * total_row_cnt); memset(cur_rrd_value, '\0', sizeof(rrd_value_t) * rrd->stat_head->ds_cnt); total_row_cnt++; cur_rra_def->row_cnt++; status = parse_tag_rra_database_row(reader, rrd, cur_rrd_value); if (status == 0) status = expect_element(reader,"/row"); } /* if (xmlStrcasecmp(element,"row")) */ else { if ( xmlStrcasecmp(element,(const xmlChar *)"/database") == 0){ xmlFree(element); break; } else { rrd_set_error("line %d: found unexpected tag: %s", xmlTextReaderGetParserLineNumber(reader),element); status = -1; } } xmlFree(element); if (status != 0) break; } /* Set the RRA pointer to a random location */ cur_rra_ptr->cur_row = rrd_random() % cur_rra_def->row_cnt; /* * rotate rows to match cur_row... * * this will require some extra temp. memory. We can do this rather * brainlessly, because we have done all kinds of realloc before, * so we messed around with memory a lot already. */ /* What we want: +-start_row_cnt | +-cur_rra_def->row_cnt | | |a---------n012-------------------------| (cur_rra_def->row_cnt slots of ds_cnt width) What we have | |012-------------------------a---------n| Do this by: copy away 0..(a-1) to a temp buffer move a..n to start of buffer copy temp buffer to position after where we moved n to */ int a = cur_rra_def->row_cnt - cur_rra_ptr->cur_row - 1; rrd_value_t *temp = malloc(ds_cnt * sizeof(rrd_value_t) * a); if (temp == NULL) { rrd_set_error("parse_tag_rra: malloc failed."); return -1; } rrd_value_t *start = rrd->rrd_value + start_row_cnt * ds_cnt; /* */ memcpy(temp, start, a * ds_cnt * sizeof(rrd_value_t)); memmove(start, start + a * ds_cnt, (cur_rra_ptr->cur_row + 1) * ds_cnt * sizeof(rrd_value_t)); memcpy(start + (cur_rra_ptr->cur_row + 1) * ds_cnt, temp, a * ds_cnt * sizeof(rrd_value_t)); free(temp); return (status); } /* int parse_tag_rra_database */
static int parse_tag_rra( xmlTextReaderPtr reader, rrd_t *rrd) { int status; xmlChar *element; rra_def_t *cur_rra_def; cdp_prep_t *cur_cdp_prep; rra_ptr_t *cur_rra_ptr; /* Allocate more rra_def space for this RRA */ { /* {{{ */ rra_def_t *temp; temp = (rra_def_t *) realloc(rrd->rra_def, sizeof(rra_def_t) * (rrd->stat_head->rra_cnt + 1)); if (temp == NULL) { rrd_set_error("parse_tag_rra: realloc failed."); return (-1); } rrd->rra_def = temp; cur_rra_def = rrd->rra_def + rrd->stat_head->rra_cnt; memset(cur_rra_def, '\0', sizeof(rra_def_t)); } /* }}} */ /* allocate cdp_prep_t */ { /* {{{ */ cdp_prep_t *temp; temp = (cdp_prep_t *) realloc(rrd->cdp_prep, sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt * (rrd->stat_head->rra_cnt + 1)); if (temp == NULL) { rrd_set_error("parse_tag_rra: realloc failed."); return (-1); } rrd->cdp_prep = temp; cur_cdp_prep = rrd->cdp_prep + (rrd->stat_head->ds_cnt * rrd->stat_head->rra_cnt); memset(cur_cdp_prep, '\0', sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt); } /* }}} */ /* allocate rra_ptr_t */ { /* {{{ */ rra_ptr_t *temp; temp = (rra_ptr_t *) realloc(rrd->rra_ptr, sizeof(rra_ptr_t) * (rrd->stat_head->rra_cnt + 1)); if (temp == NULL) { rrd_set_error("parse_tag_rra: realloc failed."); return (-1); } rrd->rra_ptr = temp; cur_rra_ptr = rrd->rra_ptr + rrd->stat_head->rra_cnt; memset(cur_rra_ptr, '\0', sizeof(rra_ptr_t)); } /* }}} */ /* All space successfully allocated, increment number of RRAs. */ rrd->stat_head->rra_cnt++; status = 0; while ((element = get_xml_element(reader)) != NULL){ if (xmlStrcasecmp(element, (const xmlChar *) "cf") == 0) status = parse_tag_rra_cf(reader, cur_rra_def); else if (xmlStrcasecmp(element, (const xmlChar *) "pdp_per_row") == 0) status = get_xml_ulong(reader, &cur_rra_def->pdp_cnt); else if (atoi(rrd->stat_head->version) == 1 && xmlStrcasecmp(element, (const xmlChar *) "xff") == 0) status = get_xml_double(reader, (double *) &cur_rra_def-> par[RRA_cdp_xff_val].u_val); else if (atoi(rrd->stat_head->version) >= 2 && xmlStrcasecmp(element, (const xmlChar *) "params") == 0){ xmlFree(element); status = parse_tag_rra_params(reader, cur_rra_def); if (status == 0) continue; else return status; } else if (xmlStrcasecmp(element, (const xmlChar *) "cdp_prep") == 0){ xmlFree(element); status = parse_tag_rra_cdp_prep(reader, rrd, cur_cdp_prep); if (status == 0) continue; else return status; } else if (xmlStrcasecmp(element, (const xmlChar *) "database") == 0){ xmlFree(element); status = parse_tag_rra_database(reader, rrd); if (status == 0) continue; else return status; } else if (xmlStrcasecmp(element,(const xmlChar *) "/rra") == 0){ xmlFree(element); return status; } /* }}} */ else { rrd_set_error("line %d: parse_tag_rra: Unknown tag: %s", xmlTextReaderGetParserLineNumber(reader), element); status = -1; } if (status != 0) { xmlFree(element); return status; } status = expect_element_end(reader,(char *)element); xmlFree(element); if (status != 0) { return status; } } /* Set the RRA pointer to a random location */ cur_rra_ptr->cur_row = rrd_random() % cur_rra_def->row_cnt; return (status); } /* int parse_tag_rra */