2016-04-27 51 views
0

如何使用数组值来映射地图?如何在avro-c中使用数组作为地图的值

我使用avro1.7.7和我的模式是这样的:

{ 
    "type":"map", 
    "values":{ 
     "type":"array", 
     "items":"int" 
    } 
} 

我的计划是这样的:

的main.c

/* 
* File: main.c 
* Author: zwlin 
* 
* Created on 2016年4月21日, 下午5:16 
*/ 

#include <stdio.h> 
#include <stdarg.h> 
#include <avro.h> 

#define iout(i); sout("%d",i); 
#define cout(c); sout("%c",c); 
#define lout(l); sout("%ld",l); 
#define piout(str,i); sout("%s:%d",str,i); 
#define psout(str,s); sout("%s:%s",str,s); 
#define pcout(str,c); sout("%s:%c",str,c); 
#define plout(str,l);sout("%s,%l",str,l); 

//for output 

void sout(const char *format, ...) { 
    va_list args; 
    va_start(args, format); 
    vfprintf(stdout, format, args); 
    fprintf(stdout, "\n"); 
    va_end(args); 
} 

int main() { 
    int res, i, j, k; 

    avro_schema_t schema; 
    avro_datum_t rec; 

    //schema 
    avro_schema_t int_array_schema = avro_schema_array(avro_schema_int()); 
    avro_schema_t int_map_schema = avro_schema_map(int_array_schema); 
    avro_schema_t int_union_schema = avro_schema_union(); 
    avro_schema_union_append(int_union_schema, int_map_schema); 
    avro_schema_union_append(int_union_schema, avro_schema_null()); 

    //choose schema 
    // schema = int_array_schema; 
    schema = int_map_schema; 
    // schema = int_union_schema; 

    //print schema 
    char schemaPrintBuf [1024]; 
    avro_writer_t jswriter = avro_writer_memory(schemaPrintBuf, 1024); 
    avro_schema_to_json(schema, jswriter); 
    psout("schema", schemaPrintBuf); 


    //data 
    int intry[] = {9, 8, 7, 6, 5, 4, 3}; 
    avro_datum_t int_array = avro_array(int_array_schema); 
    for (i = 0; i < 7; ++i) { 
     avro_datum_t vt = avro_int32(intry[i]); 
     res = avro_array_append_datum(int_array, vt); 
     avro_datum_decref(vt); 
    } 
    avro_datum_t int_map = avro_map(int_map_schema); 
    res = avro_map_set(int_map, "intarray", int_array); 
    avro_datum_decref(int_array); 
    avro_datum_t int_a_union_datum = avro_union(int_union_schema, 0, int_map); 

    //choose data 
    // rec = int_array; 
    rec = int_map; 
    // rec = int_a_union_datum; 

    //print data detail 
    sout(""); 
    char * json; 
    sout("rec:"); 
    avro_datum_to_json(rec, 0, &json); 
    sout(json); 

    //serialize 
    char buf[1024]; 
    avro_writer_t writer = avro_writer_memory(buf, 1024); 
    res = avro_write_data(writer, schema, rec); 
    if (res) { 
     psout("write result", avro_strerror()); 
    } 
    long len = avro_size_data(writer, schema, rec); 
    piout("data len", len); 

    //read 
    avro_reader_t reader = avro_reader_memory(buf, 1024); 
    avro_datum_t rslt; 
    res = avro_read_data(reader, schema, schema, &rslt); 
    if (res) { 
     psout("read error ", avro_strerror()); 
    } 

    //read data 
    sout(""); 
    sout("rslt:"); 
    avro_datum_to_json(rslt, 0, &json); 
    sout(json); 
    return 0; 
} 

这是我的目标架构:avro_schema_t模式;
这是我的数据:avro_datum_t rec;

//choose schema//choose data部分,

如果schema = int_array_schemarec = int_array
输出是这样的:
int_arry_schema output picture

如果schema = int_map_schemarec = int_map
输出是这样的:
int_map_schema output picture
分割错误出现在这里:res = avro_write_data(writer, schema, rec);

那么,我怎样才能有一个与数组的地图,因为它的值?

+0

将'必须用vprintf'翻译成英文。 – v7d8dpo4

+0

这不是很重要,所以我删除它。我编辑了格式。它更好吗?@ v7d8dpo4 – zwlin

回答

0

您似乎没有在代码方面做任何错误;然而,它看起来像项目转移到'通用价值'格式并且实现了新API的传统包装,看起来这是一个向后兼容性的错误。

如果您重新从你在你的代码生成的JSON的模式,它的工作原理,这似乎预示着一个功能回归:

所以在这里,如果我们生成模式的新副本:

psout("schema", schemaPrintBuf); 
avro_schema_t from_json; 
if (!avro_schema_from_json_literal(schemaPrintBuf, &from_json)) { 
    fprintf(stderr, "Cannot convert from json literal: %s", avro_strerror()); 
    exit(1); 
} 

// then in the write: 
res = avro_write_data(writer, from_json, rec); 

它不再崩溃 - 这是只替换那个单一的模式引用 - 如果你重新读取其他引用模式,它看起来像它的工作。

另外,因为您构建了一个基于已知,人工构建的架构avro_datum_t,您可以禁用作家验证,这似乎是崩溃的由来:

res = avro_write_data(writer, NULL, rec); 

不会在这种情况下崩溃 - 在这种情况下,这可能是模式验证的一些复杂性。

+0

它仍然崩溃时,我用户的JSON架构。但它在我禁用编写器验证时起作用!谢谢! – zwlin

相关问题