<HTML><BODY><div>LGTM.</div><div> </div><div> </div><blockquote style="border-left:1px solid #0857A6; margin:10px; padding:0 0 0 10px;">Четверг, 20 августа 2020, 0:35 +03:00 от Cyrill Gorcunov <gorcunov@gmail.com>:<br> <div id=""><div class="js-helper js-readmsg-msg"><style type="text/css"></style><div><div id="style_15978729370586787284_BODY">These msgpack entries will be needed to write them<br>down to a journal without involving txn engine. Same<br>time we would like to be able to allocate them on stack,<br>for this sake the binary form is predefined.<br><br>Part-of #5129<br><br>Signed-off-by: Cyrill Gorcunov <<a href="/compose?To=gorcunov@gmail.com">gorcunov@gmail.com</a>><br>---<br> src/box/txn_limbo.c | 9 +++++++--<br> src/box/xrow.c | 41 ++++++++++++++++++-----------------------<br> src/box/xrow.h | 20 +++++++++++++++-----<br> 3 files changed, 40 insertions(+), 30 deletions(-)<br><br>diff --git a/src/box/txn_limbo.c b/src/box/txn_limbo.c<br>index c6a4e5efc..e458dad75 100644<br>--- a/src/box/txn_limbo.c<br>+++ b/src/box/txn_limbo.c<br>@@ -283,6 +283,11 @@ txn_limbo_write_synchro(struct txn_limbo *limbo, uint32_t type, int64_t lsn)<br>  .lsn = lsn,<br>  };<br> <br>+ /*<br>+ * This is a synchronous commit so we can<br>+ * use body and row allocated on a stack.<br>+ */<br>+ struct synchro_body_bin body;<br>  struct xrow_header row;<br>  struct request request = {<br>  .header = &row,<br>@@ -292,8 +297,8 @@ txn_limbo_write_synchro(struct txn_limbo *limbo, uint32_t type, int64_t lsn)<br>  if (txn == NULL)<br>  goto rollback;<br> <br>- if (xrow_encode_synchro(&row, &txn->region, &req) != 0)<br>- goto rollback;<br>+ xrow_encode_synchro(&row, &body, &req);<br>+<br>  /*<br>  * This is not really a transaction. It just uses txn API<br>  * to put the data into WAL. And obviously it should not<br>diff --git a/src/box/xrow.c b/src/box/xrow.c<br>index bf174c701..9c6fb4fc1 100644<br>--- a/src/box/xrow.c<br>+++ b/src/box/xrow.c<br>@@ -893,35 +893,30 @@ xrow_encode_dml(const struct request *request, struct region *region,<br>  return iovcnt;<br> }<br> <br>-int<br>-xrow_encode_synchro(struct xrow_header *row, struct region *region,<br>+void<br>+xrow_encode_synchro(struct xrow_header *row,<br>+ struct synchro_body_bin *body,<br>  const struct synchro_request *req)<br> {<br>- size_t len = mp_sizeof_map(2) + mp_sizeof_uint(IPROTO_REPLICA_ID) +<br>- mp_sizeof_uint(req->replica_id) +<br>- mp_sizeof_uint(IPROTO_LSN) + mp_sizeof_uint(req->lsn);<br>- char *buf = (char *)region_alloc(region, len);<br>- if (buf == NULL) {<br>- diag_set(OutOfMemory, len, "region_alloc", "buf");<br>- return -1;<br>- }<br>- char *pos = buf;<br>-<br>- pos = mp_encode_map(pos, 2);<br>- pos = mp_encode_uint(pos, IPROTO_REPLICA_ID);<br>- pos = mp_encode_uint(pos, req->replica_id);<br>- pos = mp_encode_uint(pos, IPROTO_LSN);<br>- pos = mp_encode_uint(pos, req->lsn);<br>+ /*<br>+ * A map with two elements. We don't compress<br>+ * numbers to have this structure constant in size,<br>+ * which allows us to preallocate it on stack.<br>+ */<br>+ body->m_body = 0x80 | 2;<br>+ body->k_replica_id = IPROTO_REPLICA_ID;<br>+ body->m_replica_id = 0xce;<br>+ body->v_replica_id = mp_bswap_u32(req->replica_id);<br>+ body->k_lsn = IPROTO_LSN;<br>+ body->m_lsn = 0xcf;<br>+ body->v_lsn = mp_bswap_u64(req->lsn);<br> <br>  memset(row, 0, sizeof(*row));<br> <br>- row->body[0].iov_base = buf;<br>- row->body[0].iov_len = len;<br>- row->bodycnt = 1;<br>-<br>  row->type = req->type;<br>-<br>- return 0;<br>+ row->body[0].iov_base = (void *)body;<br>+ row->body[0].iov_len = sizeof(*body);<br>+ row->bodycnt = 1;<br> }<br> <br> int<br>diff --git a/src/box/xrow.h b/src/box/xrow.h<br>index 02dca74e5..20e82034d 100644<br>--- a/src/box/xrow.h<br>+++ b/src/box/xrow.h<br>@@ -240,16 +240,26 @@ struct synchro_request {<br>  int64_t lsn;<br> };<br> <br>+/** Synchro request xrow's body in MsgPack format. */<br>+struct PACKED synchro_body_bin {<br>+ uint8_t m_body;<br>+ uint8_t k_replica_id;<br>+ uint8_t m_replica_id;<br>+ uint32_t v_replica_id;<br>+ uint8_t k_lsn;<br>+ uint8_t m_lsn;<br>+ uint64_t v_lsn;<br>+};<br>+<br> /**<br>  * Encode synchronous replication request.<br>  * @param row xrow header.<br>- * @param region Region to use to encode the confirmation body.<br>+ * @param body Desination to use to encode the confirmation body.<br>  * @param req Request parameters.<br>- * @retval -1 on error.<br>- * @retval 0 success.<br>  */<br>-int<br>-xrow_encode_synchro(struct xrow_header *row, struct region *region,<br>+void<br>+xrow_encode_synchro(struct xrow_header *row,<br>+ struct synchro_body_bin *body,<br>  const struct synchro_request *req);<br> <br> /**<br>--<br>2.26.2<br> </div></div></div></div></blockquote><div>--<br>Serge Petrenko</div></BODY></HTML>