2016-04-27 79 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

相關問題