From ff4ca605388d143025085ddb52d4145c54f8b49f Mon Sep 17 00:00:00 2001
From: Yuriy Vostrikov <vostrikov@corp.mail.ru>
Date: Fri, 19 Nov 2010 14:49:02 +0300
Subject: [PATCH] [box] Use vector io only if tuple is big enough.

---
 mod/silverbox/box.c | 29 +++++++++++++++++++++++++----
 1 file changed, 25 insertions(+), 4 deletions(-)

diff --git a/mod/silverbox/box.c b/mod/silverbox/box.c
index ecd4dbe8b9..66d6d4419a 100644
--- a/mod/silverbox/box.c
+++ b/mod/silverbox/box.c
@@ -62,6 +62,21 @@ const struct field ASTERISK = {
 /* hooks */
 typedef int (*box_hook_t) (struct box_txn * txn);
 
+
+/*
+  For tuples of size below this threshold, when sending a tuple
+  to the client, make a deep copy of the tuple for the duration
+  of sending rather than increment a reference counter.
+  This is necessary to avoid excessive page splits when taking
+  a snapshot: many small tuples can be accessed by clients
+  immediately after the snapshot process has forked off,
+  thus incrementing tuple ref count, and causing the OS to
+  create a copy of the memory page for the forked
+  child.
+*/
+
+const int BOX_REF_THRESHOLD = 8196;
+
 struct namespace namespace[256];
 
 struct box_snap_row {
@@ -887,12 +902,18 @@ prepare_update_fields(struct box_txn *txn, struct tbuf *data)
 static void
 tuple_add_iov(struct box_txn *txn, struct box_tuple *tuple)
 {
-	tuple_txn_ref(txn, tuple);
+	size_t len;
 
-	add_iov(&tuple->bsize,
-		tuple->bsize +
+	len = tuple->bsize +
 		field_sizeof(struct box_tuple, bsize) +
-		field_sizeof(struct box_tuple, cardinality));
+		field_sizeof(struct box_tuple, cardinality);
+
+	if (len > BOX_REF_THRESHOLD) {
+		tuple_txn_ref(txn, tuple);
+		add_iov(&tuple->bsize, len);
+	} else {
+		add_iov_dup(&tuple->bsize, len);
+	}
 }
 
 static int __noinline__
-- 
GitLab