2016-04-27 10 views
0

どのように配列の値を持つマップを持つことができますか?avro-cでマップの値として配列を使用する方法

私はavro1.7.7を使用して、私のスキーマは、このようなものです:

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

私のプログラムは、このようなものです:これは私のターゲット・スキーマである

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

のmain.c:avro_schema_t schema;
これは私のデータです:avro_datum_t rec;

//choose schema

//choose data部、

出力は次のようである
schema = int_array_schema場合rec = int_array
int_map_schema output picture
:出力は次のようである
schema = int_map_schema場合rec = int_map
int_arry_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

関連する問題