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;
}

Reply via email to