Thanks Doug, I am currently doing the same but the function avro_value_decref does not work as expected for nested records. I am attaching my test code where I have modified the PERSON_SCHEMA to chnage the record "person" to have a sub-field "FullName" which in turn is a record containing two field firstname and lastname.
The problem is when I try to decref the avro variable for the sub-record, I get a segmentation fault. Attached is the source code for your reference. The issue occurs for line number 117 and 177. currently I have commented out those two lines. If this program runs 24x7 to parse constantly generated files, do u think there can be a possibility of a memory leak if line 117 and 177 and are left commented out? Thanks, Vikas On Sun, Nov 30, 2014 at 6:12 AM, Douglas Creager <[email protected]> wrote: > > While invoking the avro_generic_value_free function, I get the error, > > implementation not defined. > > > > I looked through header file but couldn’t find the function. > > > > Is this a known issue? > > That looks like a bug in the documentation. Try avro_value_decref > instead. > > cheers > –doug > -- Thanks and regards, Vikas Saxena.
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to you under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ //changelog: added nested recodes // #include <avro.h> #include <stdio.h> #include <stdlib.h> #ifdef DEFLATE_CODEC #define QUICKSTOP_CODEC "deflate" #else #define QUICKSTOP_CODEC "null" #endif avro_schema_t person_schema; int64_t id_val = 0; /* A simple schema for our tutorial */ const char PERSON_SCHEMA[] = "{\"type\":\"record\",\ \"name\":\"Person\",\ \"fields\":[\ {\"name\": \"ID\", \"type\": \"long\"},\ {\"name\": \"FullName\",\ \"type\": {\ \"name\": \"PersonName\",\ \"type\": \"record\",\ \"fields\":[\ {\"name\": \"First\", \"type\": \"string\"},\ {\"name\": \"Last\", \"type\": \"string\"}]}},\ {\"name\": \"Phone\", \"type\": \"string\"},\ {\"name\": \"Age\", \"type\": \"int\"}]}"; /* Parse schema into a schema data structure */ void init_schema(void) { if (avro_schema_from_json_literal(PERSON_SCHEMA, &person_schema)) { fprintf(stderr, "Unable to parse person schema\nMessage:%s\n",avro_strerror()); exit(EXIT_FAILURE); } } /* Create a value to match the person schema and save it */ void add_person(avro_file_writer_t db, const char *first, const char *last, const char *phone, int32_t age) { //added for avro_value_t avro_value_iface_t *iface = avro_generic_class_from_schema(person_schema); avro_value_t person; avro_generic_value_new(iface,&person); size_t index=0; avro_value_t id; avro_value_t fullName; avro_value_t firstName; avro_value_t lastName; avro_value_t phoneNumber; avro_value_t age_in_years; if(avro_value_get_by_name(&person,"ID",&id,&index)==0) { //fprintf(stdout,"id=%ld\n",id_val); avro_value_set_long(&id,++id_val); } if(avro_value_get_by_name(&person,"FullName",&fullName,&index)==0) { if(avro_value_get_by_name(&fullName,"First",&firstName,&index)==0) { avro_value_set_string(&firstName,first); } if(avro_value_get_by_name(&fullName,"Last",&lastName,&index)==0) { avro_value_set_string(&lastName,last); } } if(avro_value_get_by_name(&person,"Phone",&phoneNumber,&index)==0) { avro_value_set_string(&phoneNumber,phone); } if(avro_value_get_by_name(&person,"Age",&age_in_years,&index)==0) { avro_value_set_int(&age_in_years,age); } if (avro_file_writer_append_value(db, &person)) { fprintf(stderr, "Unable to write Person value to memory buffer\nMessage: %s\n", avro_strerror()); exit(EXIT_FAILURE); } /* Decrement all our references to prevent memory from leaking */ avro_value_reset(&id); avro_value_reset(&firstName); avro_value_reset(&lastName); avro_value_reset(&age_in_years); avro_value_reset(&phoneNumber); avro_value_reset(&fullName); avro_value_decref(&firstName); avro_value_decref(&lastName); //avro_value_decref(&fullName); //causes seg fault avro_value_decref(&person); avro_value_iface_decref(iface); //fprintf(stdout, "Successfully added %s, %s id=%"PRId64"\n", last, first, id); } int print_person(avro_file_reader_t db, avro_schema_t reader_schema) { int rval; avro_value_iface_t *iface=avro_generic_class_from_schema(reader_schema); avro_value_t person; avro_generic_value_new(iface,&person); size_t index=0; rval = avro_file_reader_read_value(db, &person); //fprintf(stdout,"rval=%d\n",rval); if (rval == 0) { int64_t i64; int32_t i32; const char *p; avro_value_t id_value,fullName_value, first_value, last_value, phone_value, age_value; if (avro_value_get_by_name(&person, "ID", &id_value, &index) == 0) { avro_value_get_long(&id_value, &i64); fprintf(stdout, "%ld | ", i64); } if (avro_value_get_by_name(&person, "FullName", &fullName_value, &index) == 0) { //fprintf(stdout,"\ninside FullName\n"); if (avro_value_get_by_name(&fullName_value, "First", &first_value, &index) == 0) { avro_value_get_string(&first_value, &p, NULL); fprintf(stdout, "%15s | ", p); } if (avro_value_get_by_name(&fullName_value, "Last", &last_value, &index) == 0) { avro_value_get_string(&last_value, &p, NULL); fprintf(stdout, "%15s | ", p); } } if (avro_value_get_by_name(&person, "Phone", &phone_value, &index) == 0) { avro_value_get_string(&phone_value, &p, NULL); fprintf(stdout, "%15s | ", p); } if (avro_value_get_by_name(&person, "Age", &age_value, &index) == 0) { avro_value_get_int(&age_value, &i32); fprintf(stdout, "%d", i32); } fprintf(stdout, "\n"); /* We no longer need this memory */ avro_value_reset(&id_value); avro_value_reset(&first_value); avro_value_reset(&last_value); avro_value_reset(&age_value); avro_value_reset(&phone_value); avro_value_reset(&fullName_value); avro_value_decref(&first_value); avro_value_decref(&last_value); //avro_value_decref(&fullName_value); //causes seg fault avro_value_decref(&person); avro_value_iface_decref(iface); } return rval; } int main(void) { int rval; avro_file_reader_t dbreader; avro_file_writer_t db; //avro_schema_t projection_schema, first_name_schema, phone_schema; int64_t i; const char *dbname = "quickstop_nestedRecord.db"; char number[15] = {0}; /* Initialize the schema structure from JSON */ init_schema(); /* Delete the database if it exists */ remove(dbname); /* Create a new database */ rval = avro_file_writer_create_with_codec (dbname, person_schema, &db, QUICKSTOP_CODEC, 0); if (rval) { fprintf(stderr, "There was an error creating %s\n", dbname); fprintf(stderr, " error message: %s\n", avro_strerror()); exit(EXIT_FAILURE); } /* Add lots of people to the database */ for (i = 0; i<2; i++) { sprintf(number, "(%d)", (int)i); add_person(db, "Dante", "Hicks", number, 32); add_person(db, "Randal", "Graves", "(555) 123-5678", 30); add_person(db, "Veronica", "Loughran", "(555) 123-0987", 28); add_person(db, "Caitlin", "Bree", "(555) 123-2323", 27); add_person(db, "Bob", "Silent", "(555) 123-6422", 29); add_person(db, "Jay", "???", number, 26); } /* Close the block and open a new one */ avro_file_writer_flush(db); add_person(db, "Super", "Man", "123456", 31); avro_file_writer_close(db); fprintf(stdout, "Now let's read all the records back out\n"); /* Read all the records and print them */ if (avro_file_reader(dbname, &dbreader)) { fprintf(stderr, "Error opening file: %s\n", avro_strerror()); exit(EXIT_FAILURE); } for (i = 0; i < id_val; i++) { if (print_person(dbreader, person_schema)) { fprintf(stderr, "Error printing person\nMessage: %s\n", avro_strerror()); exit(EXIT_FAILURE); } } avro_file_reader_close(dbreader); return 0; }
