From e066ee333ce069149fa1fcb8fcc84b9550eb213b Mon Sep 17 00:00:00 2001
From: Konstantin Osipov <kostja@tarantool.org>
Date: Fri, 12 Oct 2012 23:13:32 +0400
Subject: [PATCH] Remove port_add_u32, port_dup_u32.

Remove ugly port_add_u32, port_dup_u32.
Now there are only port methods to add a tuple.
An additional method, port_eof(), is introduced
to mark the end of a result set.

Count tuples of SELECT automatically in port_iproto,
where it is needed.
---
 mod/box/box_lua.m | 12 +++----
 mod/box/port.h    | 29 ++++++----------
 mod/box/port.m    | 88 +++++++++++++++++++++++------------------------
 mod/box/request.m | 32 ++++++-----------
 4 files changed, 69 insertions(+), 92 deletions(-)

diff --git a/mod/box/box_lua.m b/mod/box/box_lua.m
index b0a0c435a4..8199e8eb3a 100644
--- a/mod/box/box_lua.m
+++ b/mod/box/box_lua.m
@@ -888,7 +888,8 @@ port_lua(struct port *port) { return (struct port_lua *) port; }
  */
 
 static void
-port_lua_add_tuple(struct port *port, struct tuple *tuple)
+port_lua_add_tuple(struct port *port, struct tuple *tuple,
+		   u32 flags __attribute__((unused)))
 {
 	lua_State *L = port_lua(port)->L;
 	@try {
@@ -899,9 +900,8 @@ port_lua_add_tuple(struct port *port, struct tuple *tuple)
 }
 
 struct port_vtab port_lua_vtab = {
-	port_null_add_u32,
-	port_null_dup_u32,
 	port_lua_add_tuple,
+	port_null_eof,
 };
 
 static struct port *
@@ -1068,7 +1068,7 @@ port_add_lua_ret(struct port *port, struct lua_State *L, int index)
 		break;
 	}
 	@try {
-		port_add_tuple(port, tuple);
+		port_add_tuple(port, tuple, BOX_RETURN_TUPLE);
 	} @finally {
 		if (tuple->refs == 0)
 			tuple_free(tuple);
@@ -1084,11 +1084,9 @@ port_add_lua_ret(struct port *port, struct lua_State *L, int index)
  * then each return value as a tuple.
  */
 static void
-port_add_lua_multret(struct port *port __attribute__((unused)),
-			    struct lua_State *L)
+port_add_lua_multret(struct port *port, struct lua_State *L)
 {
 	int nargs = lua_gettop(L);
-	port_dup_u32(port, nargs);
 	for (int i = 1; i <= nargs; ++i)
 		port_add_lua_ret(port, L, i);
 }
diff --git a/mod/box/port.h b/mod/box/port.h
index df5ca3f417..2e43ec0091 100644
--- a/mod/box/port.h
+++ b/mod/box/port.h
@@ -35,9 +35,9 @@ struct port;
 
 struct port_vtab
 {
-	u32* (*add_u32)(struct port *port);
-	void (*dup_u32)(struct port *port, u32 num);
-	void (*add_tuple)(struct port *port, struct tuple *tuple);
+	void (*add_tuple)(struct port *port, struct tuple *tuple, u32 flags);
+	/** Must be called in the end of execution of a single request. */
+	void (*eof)(struct port *port);
 };
 
 struct port
@@ -52,33 +52,24 @@ struct port
  */
 void iov_ref_tuple(struct tuple *tuple);
 
-static inline u32*
-port_add_u32(struct port *port)
-{
-	return (port->vtab->add_u32)(port);
-}
-
 static inline void
-port_dup_u32(struct port *port, u32 num)
+port_eof(struct port *port)
 {
-	(port->vtab->dup_u32)(port, num);
+	return (port->vtab->eof)(port);
 }
 
 static inline void
-port_add_tuple(struct port *port, struct tuple *tuple)
+port_add_tuple(struct port *port, struct tuple *tuple, u32 flags)
 {
-	(port->vtab->add_tuple)(port, tuple);
+	(port->vtab->add_tuple)(port, tuple, flags);
 }
 
 /** Reused in port_lua */
-u32*
-port_null_add_u32(struct port *port __attribute__((unused)));
-
 void
-port_null_dup_u32(struct port *port __attribute__((unused)),
-		  u32 num __attribute__((unused)));
+port_null_eof(struct port *port __attribute__((unused)));
 
-/** These do not have state currently, thus a single
+/**
+ * This one does not have state currently, thus a single
  * instance is sufficient.
  */
 extern struct port port_null;
diff --git a/mod/box/port.m b/mod/box/port.m
index c5ad6c6b4a..987c25abb8 100644
--- a/mod/box/port.m
+++ b/mod/box/port.m
@@ -66,74 +66,72 @@ iov_ref_tuple(struct tuple *tuple)
 	fiber_register_cleanup(tuple_unref, tuple);
 }
 
-u32*
-port_null_add_u32(struct port *port __attribute__((unused)))
-{
-	static u32 dummy;
-	return &dummy;
-}
-
 void
-port_null_dup_u32(struct port *port __attribute__((unused)),
-		  u32 num __attribute__((unused)))
+port_null_eof(struct port *port __attribute__((unused)))
 {
 }
 
 static void
 port_null_add_tuple(struct port *port __attribute__((unused)),
-		    struct tuple *tuple __attribute__((unused)))
+		    struct tuple *tuple __attribute__((unused)),
+		    u32 flags __attribute__((unused)))
 {
 }
 
-static u32*
-port_iproto_add_u32(struct port *port __attribute__((unused)))
+static struct port_vtab port_null_vtab = {
+	port_null_add_tuple,
+	port_null_eof,
+};
+
+struct port port_null = {
+	.vtab = &port_null_vtab,
+};
+
+struct port_iproto
+{
+	struct port_vtab *vtab;
+	/** Number of found tuples. */
+	u32 found;
+};
+
+static inline struct port_iproto *
+port_iproto(struct port *port)
 {
-	u32 *p_u32 = palloc(fiber->gc_pool, sizeof(u32));
-	iov_add(p_u32, sizeof(u32));
-	return p_u32;
+	return (struct port_iproto *) port;
 }
 
 static void
-port_iproto_dup_u32(struct port *port __attribute__((unused)), u32 u32)
+port_iproto_eof(struct port *ptr)
 {
-	iov_dup(&u32, sizeof(u32));
+	struct port_iproto *port = port_iproto(ptr);
+	/* found == 0 means add_tuple wasn't called at all. */
+	if (port->found == 0)
+		iov_dup(&port->found, sizeof(port->found));
 }
 
 static void
-port_iproto_add_tuple(struct port *port __attribute__((unused)),
-		      struct tuple *tuple)
+port_iproto_add_tuple(struct port *ptr, struct tuple *tuple, u32 flags)
 {
-	size_t len = tuple_len(tuple);
-
-	if (len > BOX_REF_THRESHOLD) {
-		iov_ref_tuple(tuple);
-		iov_add(&tuple->bsize, len);
-	} else {
-		iov_dup(&tuple->bsize, len);
+	struct port_iproto *port = port_iproto(ptr);
+	if (++port->found == 1) {
+		/* Found the first tuple, add tuple count. */
+		iov_add(&port->found, sizeof(port->found));
+	}
+	if (flags & BOX_RETURN_TUPLE) {
+		size_t len = tuple_len(tuple);
+
+		if (len > BOX_REF_THRESHOLD) {
+			iov_ref_tuple(tuple);
+			iov_add(&tuple->bsize, len);
+		} else {
+			iov_dup(&tuple->bsize, len);
+		}
 	}
 }
 
-static struct port_vtab port_null_vtab = {
-	port_null_add_u32,
-	port_null_dup_u32,
-	port_null_add_tuple,
-};
-
 static struct port_vtab port_iproto_vtab = {
-	port_iproto_add_u32,
-	port_iproto_dup_u32,
 	port_iproto_add_tuple,
-};
-
-struct port port_null = {
-	.vtab = &port_null_vtab,
-};
-
-struct port_iproto
-{
-	struct port_vtab *vtab;
-	/** Number of found tuples. */
-	u32 found;
+	port_iproto_eof,
 };
 
 struct port *
diff --git a/mod/box/request.m b/mod/box/request.m
index 4f755f369b..4bafa4c11c 100644
--- a/mod/box/request.m
+++ b/mod/box/request.m
@@ -65,18 +65,6 @@ read_space(struct tbuf *data)
 	return space_find(space_no);
 }
 
-static void
-port_send_tuple(u32 flags, struct port *port, struct tuple *tuple)
-{
-	if (tuple) {
-		port_dup_u32(port, 1); /* affected tuples */
-		if (flags & BOX_RETURN_TUPLE)
-			port_add_tuple(port, tuple);
-	} else {
-		port_dup_u32(port, 0); /* affected tuples. */
-	}
-}
-
 static void
 execute_replace(struct request *request, struct txn *txn, struct port *port)
 {
@@ -111,7 +99,7 @@ execute_replace(struct request *request, struct txn *txn, struct port *port)
 
 	txn_add_undo(txn, sp, old_tuple, txn->new_tuple);
 
-	port_send_tuple(flags, port, txn->new_tuple);
+	port_add_tuple(port, txn->new_tuple, flags);
 }
 
 /** {{{ UPDATE request implementation.
@@ -729,7 +717,8 @@ execute_update(struct request *request, struct txn *txn, struct port *port)
 		space_validate(sp, old_tuple, txn->new_tuple);
 	}
 	txn_add_undo(txn, sp, old_tuple, txn->new_tuple);
-	port_send_tuple(flags, port, txn->new_tuple);
+	if (txn->new_tuple)
+		port_add_tuple(port, txn->new_tuple, flags);
 }
 
 /** }}} */
@@ -748,15 +737,14 @@ execute_select(struct request *request, struct txn *txn, struct port *port)
 	if (count == 0)
 		tnt_raise(IllegalParams, :"tuple count must be positive");
 
-	uint32_t *found = port_add_u32(port);
-	*found = 0;
-
 	ERROR_INJECT_EXCEPTION(ERRINJ_TESTING);
 
+	u32 found = 0;
+
 	for (u32 i = 0; i < count; i++) {
 
 		/* End the loop if reached the limit. */
-		if (limit == *found)
+		if (limit == found)
 			return;
 
 		/* read key */
@@ -777,9 +765,9 @@ execute_select(struct request *request, struct txn *txn, struct port *port)
 				continue;
 			}
 
-			port_add_tuple(port, tuple);
+			port_add_tuple(port, tuple, BOX_RETURN_TUPLE);
 
-			if (limit == ++(*found))
+			if (limit == ++found)
 				break;
 		}
 	}
@@ -807,7 +795,8 @@ execute_delete(struct request *request, struct txn *txn, struct port *port)
 
 	txn_add_undo(txn, sp, old_tuple, NULL);
 
-	port_send_tuple(flags, port, old_tuple);
+	if (old_tuple)
+		port_add_tuple(port, old_tuple, flags);
 }
 
 /** To collects stats, we need a valid request type.
@@ -870,4 +859,5 @@ request_execute(struct request *request, struct txn *txn, struct port *port)
 		request_check_type(request->type);
 		break;
 	}
+	port_eof(port);
 }
-- 
GitLab