diff --git a/src/box/xrow.c b/src/box/xrow.c index 80e74d1979d846653d857873e97354c327b673f8..38f8dc8ea7c2136ff8e1012dfdbe70d1a5cb2e61 100644 --- a/src/box/xrow.c +++ b/src/box/xrow.c @@ -523,33 +523,29 @@ iproto_reply_vclock(struct obuf *out, const struct vclock *vclock, return 0; } -int -iproto_reply_vote(struct obuf *out, const struct ballot *ballot, - uint64_t sync, uint64_t schema_version) +size_t +mp_sizeof_ballot_max(const struct ballot *ballot) +{ + return mp_sizeof_map(1) + mp_sizeof_uint(IPROTO_BALLOT) + + mp_sizeof_map(7) + mp_sizeof_uint(IPROTO_BALLOT_IS_RO_CFG) + + mp_sizeof_bool(ballot->is_ro_cfg) + + mp_sizeof_uint(IPROTO_BALLOT_IS_RO) + + mp_sizeof_bool(ballot->is_ro) + + mp_sizeof_uint(IPROTO_BALLOT_IS_ANON) + + mp_sizeof_bool(ballot->is_anon) + + mp_sizeof_uint(IPROTO_BALLOT_IS_BOOTED) + + mp_sizeof_bool(ballot->is_booted) + + mp_sizeof_uint(IPROTO_BALLOT_VCLOCK) + + mp_sizeof_vclock_ignore0(&ballot->vclock) + + mp_sizeof_uint(IPROTO_BALLOT_GC_VCLOCK) + + mp_sizeof_vclock_ignore0(&ballot->gc_vclock) + + mp_sizeof_uint(IPROTO_BALLOT_CAN_LEAD) + + mp_sizeof_bool(ballot->can_lead); +} + +char * +mp_encode_ballot(char *data, const struct ballot *ballot) { - size_t max_size = IPROTO_HEADER_LEN + mp_sizeof_map(1) + - mp_sizeof_uint(UINT32_MAX) + mp_sizeof_map(6) + - mp_sizeof_uint(UINT32_MAX) + mp_sizeof_bool(ballot->is_ro_cfg) + - mp_sizeof_uint(UINT32_MAX) + mp_sizeof_bool(ballot->is_ro) + - mp_sizeof_uint(IPROTO_BALLOT_IS_ANON) + - mp_sizeof_bool(ballot->is_anon) + - mp_sizeof_uint(IPROTO_BALLOT_IS_BOOTED) + - mp_sizeof_bool(ballot->is_booted) + - mp_sizeof_uint(UINT32_MAX) + - mp_sizeof_vclock_ignore0(&ballot->vclock) + - mp_sizeof_uint(UINT32_MAX) + - mp_sizeof_vclock_ignore0(&ballot->gc_vclock) + - mp_sizeof_uint(IPROTO_BALLOT_CAN_LEAD) + - mp_sizeof_bool(ballot->can_lead); - - char *buf = obuf_reserve(out, max_size); - if (buf == NULL) { - diag_set(OutOfMemory, max_size, - "obuf_alloc", "buf"); - return -1; - } - - char *data = buf + IPROTO_HEADER_LEN; data = mp_encode_map(data, 1); data = mp_encode_uint(data, IPROTO_BALLOT); data = mp_encode_map(data, 7); @@ -567,6 +563,23 @@ iproto_reply_vote(struct obuf *out, const struct ballot *ballot, data = mp_encode_vclock_ignore0(data, &ballot->gc_vclock); data = mp_encode_uint(data, IPROTO_BALLOT_CAN_LEAD); data = mp_encode_bool(data, ballot->can_lead); + return data; +} + +int +iproto_reply_vote(struct obuf *out, const struct ballot *ballot, + uint64_t sync, uint64_t schema_version) +{ + size_t max_size = IPROTO_HEADER_LEN + mp_sizeof_ballot_max(ballot); + + char *buf = obuf_reserve(out, max_size); + if (buf == NULL) { + diag_set(OutOfMemory, max_size, "obuf_alloc", "buf"); + return -1; + } + + char *data = buf + IPROTO_HEADER_LEN; + data = mp_encode_ballot(data, ballot); size_t size = data - buf; assert(size <= max_size); diff --git a/src/box/xrow.h b/src/box/xrow.h index 19e38f4c44524859df89938b6659f3e1e733af36..f03450fb3ed08c80cd24dbfb1ac64d8ac5abf45c 100644 --- a/src/box/xrow.h +++ b/src/box/xrow.h @@ -470,6 +470,23 @@ struct ballot { struct vclock gc_vclock; }; +/** + * Calculate the size taken by an encoded ballot. + * @param ballot The ballot to estimate the encoded size of. + * @retval An upper bound on encoded ballot size. + */ +size_t +mp_sizeof_ballot_max(const struct ballot *ballot); + +/** + * Encode a ballot to the provided buffer. + * @param data Buffer to encode to. + * @param ballot Ballot to encode. + * @retval A pointer after the end of encoded data. + */ +char * +mp_encode_ballot(char *data, const struct ballot *ballot); + /** * Decode ballot response to IPROTO_VOTE from MessagePack. * @param row Row to decode.