diff --git a/attributes/maestro-schema.c b/attributes/maestro-schema.c index e712f4f2195d1a46d8202bec09188b54dbd96be2..b808156839205959bedc0712d9c5df7c0e558d92 100644 --- a/attributes/maestro-schema.c +++ b/attributes/maestro-schema.c @@ -2389,4 +2389,241 @@ BAILOUT: return status; } +static inline +mstro_status +mstro_attribute_entry_to_mapentry(const struct mstro_attribute_entry_ *entry, + Mstro__Pool__KvEntry **result_p) +{ + mstro_status s = MSTRO_UNIMPL; + + Mstro__Pool__KvEntry *res = malloc(sizeof(Mstro__Pool__KvEntry)); + if(res==NULL) { + ERR("Failed to allocate KV entry\n"); + s=MSTRO_NOMEM; + goto BAILOUT; + } + mstro__pool__kv_entry__init(res); + + res->val = malloc(sizeof(Mstro__Pool__AVal)); + if(res->val==NULL) { + ERR("Failed to allocat value box for KV entry\n"); + free(res); + s=MSTRO_NOMEM; + goto BAILOUT; + } + mstro__pool__aval__init(res->val); + + s=MSTRO_OK; + + switch(entry->kind) { + case MSTRO_STP_BOOL: + res->val->val_case = MSTRO__POOL__AVAL__VAL_BOOL; + res->val->bool_ = *((bool*)entry->val) ? true : false; + break; + case MSTRO_STP_UINT: + res->val->val_case = MSTRO__POOL__AVAL__VAL_UINT64; + res->val->uint64 = *((uint64_t*)entry->val); + break; + case MSTRO_STP_INT: + res->val->val_case = MSTRO__POOL__AVAL__VAL_INT64; + res->val->uint64 = *((int64_t*)entry->val); + break; + case MSTRO_STP_FLOAT: + res->val->val_case = MSTRO__POOL__AVAL__VAL_FLOAT; + res->val->float_ = *((float*)entry->val); + break; + case MSTRO_STP_DOUBLE: + res->val->val_case = MSTRO__POOL__AVAL__VAL_DOUBLE; + res->val->double_ = *((double*)entry->val); + break; + case MSTRO_STP_STR: + case MSTRO_STP_REGEX: + res->val->val_case = MSTRO__POOL__AVAL__VAL_STRING; + res->val->string = (char *)entry->val; + break; + case MSTRO_STP_BLOB: + ERR("BLOBS unsupported, FIXME\n"); + s=MSTRO_NOENT; + break; + case MSTRO_STP_POINTER: + res->val->val_case = MSTRO__POOL__AVAL__VAL_BYTES; + INFO("POINTER type not serialized\n"); + s=MSTRO_NOENT; + break; + default: + ERR("Unsupported attribute type, can not serialize: %d\n"); + s=MSTRO_FAIL; + break; + } + if(s!=MSTRO_OK) { + free(res->val); + free(res); + res=NULL; + } + +BAILOUT: + *result_p = res; + return s; +} + +static inline +void +mstro_attribute_map__mapentry_destroy(Mstro__Pool__KvEntry *entry) +{ + WARN("Leaking memory"); + /* key is shared with symbol-name */ + entry->key=NULL; + switch(entry->val->val_case) { + case MSTRO__POOL__AVAL__VAL__NOT_SET: + case MSTRO__POOL__AVAL__VAL_BOOL: + case MSTRO__POOL__AVAL__VAL_INT32: + case MSTRO__POOL__AVAL__VAL_INT64: + case MSTRO__POOL__AVAL__VAL_UINT32: + case MSTRO__POOL__AVAL__VAL_UINT64: + case MSTRO__POOL__AVAL__VAL_FLOAT: + case MSTRO__POOL__AVAL__VAL_DOUBLE: + /* immediate values */ + break; + case MSTRO__POOL__AVAL__VAL_STRING: + /* shared with dict */ + entry->val->string = NULL; + break; + case MSTRO__POOL__AVAL__VAL_BYTES: + /* shared with dict */ + entry->val->bytes.len = 0; + entry->val->bytes.data = NULL; + break; + case MSTRO__POOL__AVAL__VAL_TIMESTAMP: + /* shared with dict */ + entry->val->timestamp = NULL; + break; + default: + ERR("Unexpected mapentry type: %d\n", entry->val->val_case); + } + mstro__pool__kv_entry__free_unpacked(entry, NULL); + + return; +} + + +static inline +mstro_status +mstro_attribute_dict_to_kvmap(mstro_attribute_dict dict, + Mstro__Pool__Attributes__Map **map) +{ + mstro_status s=MSTRO_UNIMPL; + + Mstro__Pool__Attributes__Map *res = malloc(sizeof(Mstro__Pool__Attributes__Map)); + if(res==NULL) { + ERR("Cannot allocate k-v-map\n"); + s=MSTRO_NOMEM; + goto BAILOUT; + } + mstro__pool__attributes__map__init(res); + + res->n_map = HASH_COUNT(dict->dict); + if(res->n_map==0) { + res->map = NULL; + s=MSTRO_OK; + goto BAILOUT; + } + DEBUG("Dict has %zu entries\n", res->n_map); + + res->map = malloc(res->n_map * sizeof(Mstro__Pool__KvEntry*)); + if(res->map==NULL) { + ERR("Failed to allocate k-v-map array\n"); + free(res); + res=NULL; + s=MSTRO_NOMEM; + goto BAILOUT; + } + + struct mstro_attribute_entry_ *el, *tmp; + size_t i=0; + HASH_ITER(hh, dict->dict, el, tmp) { + DEBUG("serializing attribute entry %s\n", mstro_symbol_name(el->key)); + + s = mstro_attribute_entry_to_mapentry(el, &(res->map[i])); + if(s!=MSTRO_OK) { + if(s==MSTRO_NOENT) { + WARN("Skipped dictionary entry %s\n", mstro_symbol_name(el->key)); + } else { + ERR("Failed to dictionary entry %s\n", mstro_symbol_name(el->key)); + res->n_map = 0; + free(res->map); + free(res); + res=NULL; + goto BAILOUT; + } + } else { + i++; + } + } + DEBUG("Total non-serialized entries: %zu\n", res->n_map - i); + res->n_map = i; /* we could have skipped some */ + s=MSTRO_OK; + +BAILOUT: + *map = res; + + return s; +} + + +mstro_status +mstro_attribute_dict_to_message(mstro_attribute_dict dict, + Mstro__Pool__Attributes **msg_p) +{ + if(dict==NULL) { + ERR("Invalid dictionary\n"); + return MSTRO_INVARG; + } + if(msg_p==NULL) { + ERR("Invalid attribiutes destination\n"); + return MSTRO_INVOUT; + } + + Mstro__Pool__Attributes__Map *map=NULL; + mstro_status s= mstro_attribute_dict_to_kvmap(dict, &map); + if(s!=MSTRO_OK) { + ERR("Failed to construct k-v-map\n"); + return s; + } + assert(map!=NULL); + + Mstro__Pool__Attributes *res = malloc(sizeof(Mstro__Pool__Attributes)); + if(res==NULL) { + ERR("Cannot allocate attributes message\n"); + /* fixme: leaking inside */ + free(map); + return MSTRO_NOMEM; + } + mstro__pool__attributes__init(res); + res->val_case = MSTRO__POOL__ATTRIBUTES__VAL_KV_MAP; + res->kv_map = map; + /* All attribute names are fully qualified, so the we do need a + * default namespace. FIXME: we could save on message size by + * picking the 'most-used' prefix and set that, compressing names */ + res->default_namespace = NULL; + + *msg_p = res; + return MSTRO_OK; +} + +mstro_status +mstro_attribute_dict_message_dispose(mstro_attribute_dict dict, + Mstro__Pool__Attributes *msg) +{ + if(dict==NULL) + return MSTRO_INVARG; + if(msg==NULL) + return MSTRO_INVARG; + + /* FIXME: leaking here, but better safe than sorry */ + free(msg); + + return MSTRO_OK; +} + + diff --git a/attributes/maestro-schema.h b/attributes/maestro-schema.h index d01715866f1e2ae28f3bc1c5edc11ec253fc3a25..d4e288bcaecf2f9f7510bac092410e2ab4a47cb2 100644 --- a/attributes/maestro-schema.h +++ b/attributes/maestro-schema.h @@ -38,6 +38,7 @@ #include <stdbool.h> #include "maestro/status.h" +#include "protocols/mstro_pool.pb-c.h" /** An (abstract) schema handle */ struct mstro_schema_; @@ -226,4 +227,30 @@ mstro_attribute_dict_set(mstro_attribute_dict dict, const char *key, void *val, bool copy_value); +/** Create a pool manager message containing all attributes. + * + * References to values in the dictionary will be inserted, so the + * dictionary must outlive the created message. + * + * Care must be taken when destroying the message to not have the + * protobuf message disposal code free such values; always use + * mstro_attribute_dict_message_dispose on messages created by this + * function. + */ + +mstro_status +mstro_attribute_dict_to_message(mstro_attribute_dict dict, + Mstro__Pool__Attributes **msg_p); + +/** Destroy a pool manager message containing references to the values in dict. + * + * This function must be used instead of the generic protobuf deallocators to avoid freeing values still + * referenced in the dictionary. + */ +mstro_status +mstro_attribute_dict_message_dispose(mstro_attribute_dict dict, + Mstro__Pool__Attributes *msg); + + + #endif diff --git a/include/maestro/i_cdo.h b/include/maestro/i_cdo.h index 36eda4bdad0dffb588783f9d88a618ca40715e6e..fc910493f7d0512d2fa62d2e8892fa06d7db6d63 100644 --- a/include/maestro/i_cdo.h +++ b/include/maestro/i_cdo.h @@ -41,6 +41,7 @@ #include "maestro/status.h" #include "maestro/cdo.h" +#include "protocols/mstro_pool.pb-c.h" #include <mamba.h> @@ -290,6 +291,8 @@ struct mstro_cdo_ { /* all other attributes and name and id are stored in the following table */ mstro_cdo_attributes attributes; /**< attribute and schema information */ + Mstro__Pool__Attributes *attributes_msg; /**< attributes in serialized form */ + /* FIXME: we could store the current_namespace in a global namespace * symtab ... millions of CDOs that all have the same string copied * seems overkill */ diff --git a/maestro/cdo.c b/maestro/cdo.c index 67a945c8ee5b2bedc3e6d8e52d13487ef4bde438..3e6a15a890805c3c5a986f4c52bb570d7dd684c2 100644 --- a/maestro/cdo.c +++ b/maestro/cdo.c @@ -134,6 +134,7 @@ mstro_cdo__alloc(void) } /* we need to zero out the hash-table relevant parts. For simplicity we zero everything */ memset(res, 0, sizeof(struct mstro_cdo_)); + /* initialize parts that need special handling */ atomic_init(&(res->state), MSTRO_CDO_STATE_INVALID); @@ -151,6 +152,7 @@ mstro_cdo__alloc(void) ERR("Cannot create CDO, aborting\n"); abort(); } + return res; } @@ -166,6 +168,15 @@ mstro_cdo__free(mstro_cdo *cdoptr) if((*cdoptr)->name) free((*cdoptr)->name); + if((*cdoptr)->attributes_msg) { + status=mstro_attribute_dict_message_dispose((*cdoptr)->attributes, + (*cdoptr)->attributes_msg); + if(status!=MSTRO_OK) { + ERR("Failed to destoy CDO's serialized attributes\n"); + goto BAILOUT; + } + } + status = mstro_attribute_dict_dispose((*cdoptr)->attributes); if(status!=MSTRO_OK) { ERR("Failed to destroy CDO attribute table\n"); @@ -229,8 +240,10 @@ mstro_cdo_block_until(mstro_cdo cdo, mstro_cdo_state s, const char* debug) mstro_cdo_state state = atomic_load(&cdo->state); while(0 == (state & s)) { /* wait for state change */ + const struct mstro_cdo_id null_cdoid = MSTRO_CDO_ID_INVALID; WITH_CDO_ID_STR( - idstr, &cdo->gid, + /* we might be called before GID is assigned */ + idstr, mstro_cdo_id__equal(&cdo->gid, &null_cdoid) ? &cdo->id : &cdo->gid, DEBUG("cdo %s is not in %s state yet, waiting for state change\n", idstr, debug);); state = wait_for_cdo_state_change(cdo, state); @@ -368,6 +381,25 @@ mstro_cdo_declare(const char *name, return MSTRO_OK; } +/* Build the cdo->attributes_msg protobuf structure for all attributes of the CDO + * If already non-NULL, warn. + * We do not support updating it -- use mstro_cdo_attributes_merge() for that. + */ +static inline +mstro_status +mstro_cdo_ensure_attribute_msg(mstro_cdo cdo) +{ + if(cdo->attributes_msg!=NULL) { + WITH_CDO_ID_STR(idstr, &cdo->gid, + WARN("CDO %s already has attribute message\n", idstr); + ); + return MSTRO_OK; + } + + return mstro_attribute_dict_to_message(cdo->attributes, + &cdo->attributes_msg); +} + mstro_status mstro_cdo_declaration_seal(mstro_cdo cdo) { @@ -512,16 +544,17 @@ mstro_cdo_declaration_seal(mstro_cdo cdo) cdoid.qw0 = cdo->gid.qw[0]; cdoid.qw1 = cdo->gid.qw[1]; - Mstro__Pool__Attributes attr = MSTRO__POOL__ATTRIBUTES__INIT; - attr.val_case = MSTRO__POOL__ATTRIBUTES__VAL_YAML_STRING; - /* FIXME: this should use the fixed data but a serialized version - * of the current attributes */ - WARN("Sealing with silly attributes\n"); - //xx// attr.yaml_string = cdo->attributes_yaml; - + status = mstro_cdo_ensure_attribute_msg(cdo); + if(status!=MSTRO_OK) { + ERR("Failed to serialize attributes\n"); + return status; + } + assert(cdo->attributes_msg!=NULL); + + /* attributes message is preserved in cdo, so it's safe to pack into message */ Mstro__Pool__Seal seal = MSTRO__POOL__SEAL__INIT; seal.cdoid = &cdoid; - seal.attributes = &attr; + seal.attributes = cdo->attributes_msg; Mstro__Pool__MstroMsg msg = MSTRO__POOL__MSTRO_MSG__INIT; status = mstro_pmp_package(&msg, (ProtobufCMessage*)&seal); diff --git a/maestro/ofi.c b/maestro/ofi.c index b96d10ac0642c13e5fbd6529d05c4c41f8cd7c4e..9c229804a62d861739e95a6e6ad916b1f0c047d4 100644 --- a/maestro/ofi.c +++ b/maestro/ofi.c @@ -600,7 +600,7 @@ mstro_ofi_pm_info(char **result_p) * for details */ tpl_node *tn; - struct mstro_endpoint *tmp, *elt; + struct mstro_endpoint *elt; struct serialized_endpoint_element serialized_element; assert(MSTRO_EP__MAX<=INT_MAX); @@ -631,7 +631,6 @@ mstro_ofi_pm_info(char **result_p) || d->type == MSTRO_EP_OFI_MLX) { /* uint64_t based endpoints */ tpl_node *tns; - uint64_t val; /* abusing C union properties we can refer to all entries by the * gni slots; we end up always transporting 6 uint64, but who cares */ tns = tpl_map("UUUUUU", @@ -745,8 +744,6 @@ mstro_ofi_pm_info(char **result_p) } #if 1 { - size_t count = 0; - mstro_endpoint_descriptor tmp; DEBUG("serialized %d EPs to |%s|\n", g_endpoints->size, *result_p); } @@ -861,7 +858,6 @@ mstro_ep_desc_deserialize(mstro_endpoint_descriptor *result_p, /* target for list-append */ next = result_p; - size_t i=0; while( tpl_unpack( tn, 1 ) > 0 ) { /* got another element */ enum mstro_endpoint_type eptype @@ -1059,11 +1055,6 @@ mstro_ep_build_from_ofi(struct mstro_endpoint *dst, struct fid_av *av = NULL; struct fi_cq_attr cq_attr; struct fid_cq *cq = NULL; - void *addr = NULL; - size_t addrlen = 0; - char *buf=NULL; - size_t buflen = 0; - /* create fabric object */ stat = fi_fabric(fi->fabric_attr, &fabric, NULL); @@ -2809,6 +2800,17 @@ mstro_pm__handle_seal(Mstro__Pool__Seal *seal, } if(seal->attributes!=NULL) { + DEBUG("Seal attributes: default-namespace %s, kind %s\n", + seal->attributes->default_namespace == NULL + ? seal->attributes->default_namespace : "(empty)", + seal->attributes->val_case==MSTRO__POOL__ATTRIBUTES__VAL_KV_MAP + ? "kv-map" : ( + seal->attributes->val_case == MSTRO__POOL__ATTRIBUTES__VAL_YAML_STRING + ? "yaml" : "(other)")); + if(seal->attributes->val_case==MSTRO__POOL__ATTRIBUTES__VAL_KV_MAP) { + DEBUG("Seal attributes: %zu entries\n", seal->attributes->kv_map->n_map); + } + s = mstro_pm_cdo_registry_store_attributes(&cdoid, app_id, seal->attributes); if(s==MSTRO_OK) { @@ -3228,7 +3230,6 @@ mstro_ofi__loop(_Atomic bool *terminate, mstro_msg_handler incoming_msg_handler) { mstro_status status = MSTRO_OK; - ssize_t res; size_t i; struct mstro_msg_envelope** slots =calloc(g_endpoints->size, @@ -3626,25 +3627,25 @@ mstro_pm_attach(const char *remote_pm_info) const char* env_transport_default = getenv(MSTRO_ENV_TRANSPORT_DEFAULT); if (env_transport_default != NULL) { - int i, pos; - int found = 0; - for ( i = 0; i < MSTRO__POOL__TRANSPORT_KIND__NUMBER_OF_KINDS; i++ ) { - if (!strcmp(env_transport_default, g_transport_registry[i].name)) { - transport_methods.supported[0] = (Mstro__Pool__TransportKind)i; - found = 1; - INFO("Setting default transport method to %s (env %s)\n", - g_transport_registry[i].name, - MSTRO_ENV_TRANSPORT_DEFAULT); - } - } - if (! found) - WARN("default transport method given (env %s) not found, using maestro defaults\n", env_transport_default); - } - INFO("Preferred transport list: \n"); - int i; - for (i = 0; i < transport_methods.n_supported; i++ ) - INFO("#%d %s \n", i, g_transport_registry[transport_methods.supported[i]].name); - /**/ + int i; + int found = 0; + for ( i = 0; i < MSTRO__POOL__TRANSPORT_KIND__NUMBER_OF_KINDS; i++ ) { + if (!strcmp(env_transport_default, g_transport_registry[i].name)) { + transport_methods.supported[0] = (Mstro__Pool__TransportKind)i; + found = 1; + INFO("Setting default transport method to %s (env %s)\n", + g_transport_registry[i].name, + MSTRO_ENV_TRANSPORT_DEFAULT); + } + } + if (! found) + WARN("default transport method given (env %s) not found, using maestro defaults\n", env_transport_default); + } + INFO("Preferred transport list: \n"); + int i; + for (i = 0; i < transport_methods.n_supported; i++ ) + INFO("#%d %s \n", i, g_transport_registry[transport_methods.supported[i]].name); + /**/ Mstro__Pool__Join join = MSTRO__POOL__JOIN__INIT; join.serialized_endpoint = g_pm_endpoint->addr_serialized; diff --git a/protocols/mstro_pool.pb-c.c b/protocols/mstro_pool.pb-c.c index bab9c01cc267df474f01dc576f86a66e3668cf68..916acbf0738ee1099d4b6d8bb1ffed1b0dd765ae 100644 --- a/protocols/mstro_pool.pb-c.c +++ b/protocols/mstro_pool.pb-c.c @@ -592,12 +592,51 @@ void mstro__pool__aval__free_unpacked assert(message->base.descriptor == &mstro__pool__aval__descriptor); protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); } -void mstro__pool__attributes__map__kv_map_entry__init - (Mstro__Pool__Attributes__Map__KvMapEntry *message) +void mstro__pool__kv_entry__init + (Mstro__Pool__KvEntry *message) { - static const Mstro__Pool__Attributes__Map__KvMapEntry init_value = MSTRO__POOL__ATTRIBUTES__MAP__KV_MAP_ENTRY__INIT; + static const Mstro__Pool__KvEntry init_value = MSTRO__POOL__KV_ENTRY__INIT; *message = init_value; } +size_t mstro__pool__kv_entry__get_packed_size + (const Mstro__Pool__KvEntry *message) +{ + assert(message->base.descriptor == &mstro__pool__kv_entry__descriptor); + return protobuf_c_message_get_packed_size ((const ProtobufCMessage*)(message)); +} +size_t mstro__pool__kv_entry__pack + (const Mstro__Pool__KvEntry *message, + uint8_t *out) +{ + assert(message->base.descriptor == &mstro__pool__kv_entry__descriptor); + return protobuf_c_message_pack ((const ProtobufCMessage*)message, out); +} +size_t mstro__pool__kv_entry__pack_to_buffer + (const Mstro__Pool__KvEntry *message, + ProtobufCBuffer *buffer) +{ + assert(message->base.descriptor == &mstro__pool__kv_entry__descriptor); + return protobuf_c_message_pack_to_buffer ((const ProtobufCMessage*)message, buffer); +} +Mstro__Pool__KvEntry * + mstro__pool__kv_entry__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) +{ + return (Mstro__Pool__KvEntry *) + protobuf_c_message_unpack (&mstro__pool__kv_entry__descriptor, + allocator, len, data); +} +void mstro__pool__kv_entry__free_unpacked + (Mstro__Pool__KvEntry *message, + ProtobufCAllocator *allocator) +{ + if(!message) + return; + assert(message->base.descriptor == &mstro__pool__kv_entry__descriptor); + protobuf_c_message_free_unpacked ((ProtobufCMessage*)message, allocator); +} void mstro__pool__attributes__map__init (Mstro__Pool__Attributes__Map *message) { @@ -3002,7 +3041,7 @@ const ProtobufCMessageDescriptor mstro__pool__aval__descriptor = (ProtobufCMessageInit) mstro__pool__aval__init, NULL,NULL,NULL /* reserved[123] */ }; -static const ProtobufCFieldDescriptor mstro__pool__attributes__map__kv_map_entry__field_descriptors[2] = +static const ProtobufCFieldDescriptor mstro__pool__kv_entry__field_descriptors[2] = { { "key", @@ -3010,66 +3049,66 @@ static const ProtobufCFieldDescriptor mstro__pool__attributes__map__kv_map_entry PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_STRING, 0, /* quantifier_offset */ - offsetof(Mstro__Pool__Attributes__Map__KvMapEntry, key), + offsetof(Mstro__Pool__KvEntry, key), NULL, &protobuf_c_empty_string, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, { - "value", + "val", 2, PROTOBUF_C_LABEL_NONE, PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ - offsetof(Mstro__Pool__Attributes__Map__KvMapEntry, value), + offsetof(Mstro__Pool__KvEntry, val), &mstro__pool__aval__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; -static const unsigned mstro__pool__attributes__map__kv_map_entry__field_indices_by_name[] = { +static const unsigned mstro__pool__kv_entry__field_indices_by_name[] = { 0, /* field[0] = key */ - 1, /* field[1] = value */ + 1, /* field[1] = val */ }; -static const ProtobufCIntRange mstro__pool__attributes__map__kv_map_entry__number_ranges[1 + 1] = +static const ProtobufCIntRange mstro__pool__kv_entry__number_ranges[1 + 1] = { { 1, 0 }, { 0, 2 } }; -const ProtobufCMessageDescriptor mstro__pool__attributes__map__kv_map_entry__descriptor = +const ProtobufCMessageDescriptor mstro__pool__kv_entry__descriptor = { PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, - "mstro.pool.Attributes.Map.KvMapEntry", - "KvMapEntry", - "Mstro__Pool__Attributes__Map__KvMapEntry", + "mstro.pool.KvEntry", + "KvEntry", + "Mstro__Pool__KvEntry", "mstro.pool", - sizeof(Mstro__Pool__Attributes__Map__KvMapEntry), + sizeof(Mstro__Pool__KvEntry), 2, - mstro__pool__attributes__map__kv_map_entry__field_descriptors, - mstro__pool__attributes__map__kv_map_entry__field_indices_by_name, - 1, mstro__pool__attributes__map__kv_map_entry__number_ranges, - (ProtobufCMessageInit) mstro__pool__attributes__map__kv_map_entry__init, + mstro__pool__kv_entry__field_descriptors, + mstro__pool__kv_entry__field_indices_by_name, + 1, mstro__pool__kv_entry__number_ranges, + (ProtobufCMessageInit) mstro__pool__kv_entry__init, NULL,NULL,NULL /* reserved[123] */ }; static const ProtobufCFieldDescriptor mstro__pool__attributes__map__field_descriptors[1] = { { - "kv_map", + "map", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, - offsetof(Mstro__Pool__Attributes__Map, n_kv_map), - offsetof(Mstro__Pool__Attributes__Map, kv_map), - &mstro__pool__attributes__map__kv_map_entry__descriptor, + offsetof(Mstro__Pool__Attributes__Map, n_map), + offsetof(Mstro__Pool__Attributes__Map, map), + &mstro__pool__kv_entry__descriptor, NULL, 0, /* flags */ 0,NULL,NULL /* reserved1,reserved2, etc */ }, }; static const unsigned mstro__pool__attributes__map__field_indices_by_name[] = { - 0, /* field[0] = kv_map */ + 0, /* field[0] = map */ }; static const ProtobufCIntRange mstro__pool__attributes__map__number_ranges[1 + 1] = { diff --git a/protocols/mstro_pool.pb-c.h b/protocols/mstro_pool.pb-c.h index 557a8ef19003b81e43415f0db10b3442f38d38ea..2a0b02ff9491f66aa503a1cc393d6a583dfb0ac8 100644 --- a/protocols/mstro_pool.pb-c.h +++ b/protocols/mstro_pool.pb-c.h @@ -28,9 +28,9 @@ typedef struct _Mstro__Pool__Declare Mstro__Pool__Declare; typedef struct _Mstro__Pool__DeclareAck Mstro__Pool__DeclareAck; typedef struct _Mstro__Pool__Timestamp Mstro__Pool__Timestamp; typedef struct _Mstro__Pool__AVal Mstro__Pool__AVal; +typedef struct _Mstro__Pool__KvEntry Mstro__Pool__KvEntry; typedef struct _Mstro__Pool__Attributes Mstro__Pool__Attributes; typedef struct _Mstro__Pool__Attributes__Map Mstro__Pool__Attributes__Map; -typedef struct _Mstro__Pool__Attributes__Map__KvMapEntry Mstro__Pool__Attributes__Map__KvMapEntry; typedef struct _Mstro__Pool__Seal Mstro__Pool__Seal; typedef struct _Mstro__Pool__SealGroup Mstro__Pool__SealGroup; typedef struct _Mstro__Pool__Offer Mstro__Pool__Offer; @@ -416,22 +416,25 @@ struct _Mstro__Pool__AVal , MSTRO__POOL__AVAL__VAL__NOT_SET, {0} } -struct _Mstro__Pool__Attributes__Map__KvMapEntry +/* + ** Attribute key-value entry + */ +struct _Mstro__Pool__KvEntry { ProtobufCMessage base; char *key; - Mstro__Pool__AVal *value; + Mstro__Pool__AVal *val; }; -#define MSTRO__POOL__ATTRIBUTES__MAP__KV_MAP_ENTRY__INIT \ - { PROTOBUF_C_MESSAGE_INIT (&mstro__pool__attributes__map__kv_map_entry__descriptor) \ +#define MSTRO__POOL__KV_ENTRY__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&mstro__pool__kv_entry__descriptor) \ , (char *)protobuf_c_empty_string, NULL } struct _Mstro__Pool__Attributes__Map { ProtobufCMessage base; - size_t n_kv_map; - Mstro__Pool__Attributes__Map__KvMapEntry **kv_map; + size_t n_map; + Mstro__Pool__KvEntry **map; }; #define MSTRO__POOL__ATTRIBUTES__MAP__INIT \ { PROTOBUF_C_MESSAGE_INIT (&mstro__pool__attributes__map__descriptor) \ @@ -1473,9 +1476,25 @@ Mstro__Pool__AVal * void mstro__pool__aval__free_unpacked (Mstro__Pool__AVal *message, ProtobufCAllocator *allocator); -/* Mstro__Pool__Attributes__Map__KvMapEntry methods */ -void mstro__pool__attributes__map__kv_map_entry__init - (Mstro__Pool__Attributes__Map__KvMapEntry *message); +/* Mstro__Pool__KvEntry methods */ +void mstro__pool__kv_entry__init + (Mstro__Pool__KvEntry *message); +size_t mstro__pool__kv_entry__get_packed_size + (const Mstro__Pool__KvEntry *message); +size_t mstro__pool__kv_entry__pack + (const Mstro__Pool__KvEntry *message, + uint8_t *out); +size_t mstro__pool__kv_entry__pack_to_buffer + (const Mstro__Pool__KvEntry *message, + ProtobufCBuffer *buffer); +Mstro__Pool__KvEntry * + mstro__pool__kv_entry__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void mstro__pool__kv_entry__free_unpacked + (Mstro__Pool__KvEntry *message, + ProtobufCAllocator *allocator); /* Mstro__Pool__Attributes__Map methods */ void mstro__pool__attributes__map__init (Mstro__Pool__Attributes__Map *message); @@ -2226,8 +2245,8 @@ typedef void (*Mstro__Pool__Timestamp_Closure) typedef void (*Mstro__Pool__AVal_Closure) (const Mstro__Pool__AVal *message, void *closure_data); -typedef void (*Mstro__Pool__Attributes__Map__KvMapEntry_Closure) - (const Mstro__Pool__Attributes__Map__KvMapEntry *message, +typedef void (*Mstro__Pool__KvEntry_Closure) + (const Mstro__Pool__KvEntry *message, void *closure_data); typedef void (*Mstro__Pool__Attributes__Map_Closure) (const Mstro__Pool__Attributes__Map *message, @@ -2368,9 +2387,9 @@ extern const ProtobufCMessageDescriptor mstro__pool__declare__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__declare_ack__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__timestamp__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__aval__descriptor; +extern const ProtobufCMessageDescriptor mstro__pool__kv_entry__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__attributes__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__attributes__map__descriptor; -extern const ProtobufCMessageDescriptor mstro__pool__attributes__map__kv_map_entry__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__seal__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__seal_group__descriptor; extern const ProtobufCMessageDescriptor mstro__pool__offer__descriptor; diff --git a/protocols/mstro_pool.proto b/protocols/mstro_pool.proto index cdcefddb59c33e979150bbc43af2b91c74b7de82..3f143ea767d19eccc9095864d20ed55c6c26056f 100644 --- a/protocols/mstro_pool.proto +++ b/protocols/mstro_pool.proto @@ -160,6 +160,12 @@ message AVal { }; }; +/** Attribute key-value entry */ +message KvEntry { + string key = 1; + AVal val = 2; +}; + /** Attributes are either a single big YAML string or a key/value * table mapping attribute name to AVal instance. * @@ -167,8 +173,9 @@ message AVal { * (PERIOD), and relative to the DEFAULT_NAMESPACE if not. **/ message Attributes { + message Map { - map<string,AVal> kv_map = 1; + repeated KvEntry map = 1; }; string default_namespace = 1; diff --git a/tests/Makefile.am b/tests/Makefile.am index 76af787fd946abc1935468028ca0c06ce1f3d737..3c0bf97f9efae260f18c1976a87bdb77da85d45e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -40,6 +40,7 @@ TEST_INCLUDES = -I$(top_srcdir)/include \ -I$(top_srcdir)/deps/libyaml/include \ -I$(top_srcdir)/deps/libcyaml/include \ -I$(top_srcdir)/protocols \ + -I$(top_srcdir)/ \ -I$(top_srcdir)/transport \ -I$(top_srcdir)/attributes \ -I$(top_builddir)/attributes # schema_type_parse.h header is compile-time-generated