patch_optimize_mem

application/octet-stream

Filename: patch_optimize_mem
Type: application/octet-stream
Part: 0
Message: Patch: Optimize memory allocation in function 'bringetbitmap'
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 99337b0..2e92dd0 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -131,7 +131,7 @@ brininsert(PG_FUNCTION_ARGS)
 			oldcxt = MemoryContextSwitchTo(tupcxt);
 		}
 
-		dtup = brin_deform_tuple(bdesc, brtup);
+		dtup = brin_deform_tuple(bdesc, brtup, NULL, NULL, NULL);
 
 		/*
 		 * Compare the key values of the new tuple to the stored index values;
@@ -284,7 +284,12 @@ bringetbitmap(PG_FUNCTION_ARGS)
 	FmgrInfo   *consistentFn;
 	MemoryContext oldcxt;
 	MemoryContext perRangeCxt;
-
+	BrinTuple  *btup;
+	uint32	   tupInitSize;
+	Datum 	   *values;
+	bool 	   *allnulls;
+	bool 	   *hasnulls;
+	
 	opaque = (BrinOpaque *) scan->opaque;
 	bdesc = opaque->bo_bdesc;
 	pgstat_count_index_scan(idxRel);
@@ -304,7 +309,16 @@ bringetbitmap(PG_FUNCTION_ARGS)
 	 * key reference each of them.  We rely on zeroing fn_oid to InvalidOid.
 	 */
 	consistentFn = palloc0(sizeof(FmgrInfo) * bdesc->bd_tupdesc->natts);
-
+	
+	/*
+	 * Estimate the approximate size and allocate memory for tup.
+	 */
+	tupInitSize = bdesc->bd_tupdesc->natts * 16;
+	btup = palloc(tupInitSize);
+	values = palloc(sizeof(Datum) * bdesc->bd_totalstored);
+	allnulls = palloc(sizeof(bool) * bdesc->bd_tupdesc->natts);
+	hasnulls = palloc(sizeof(bool) * bdesc->bd_tupdesc->natts);
+	
 	/*
 	 * Setup and use a per-range memory context, which is reset every time we
 	 * loop below.  This avoids having to free the tuples within the loop.
@@ -327,7 +341,6 @@ bringetbitmap(PG_FUNCTION_ARGS)
 		BrinTuple  *tup;
 		OffsetNumber off;
 		Size		size;
-
 		CHECK_FOR_INTERRUPTS();
 
 		MemoryContextResetAndDeleteChildren(perRangeCxt);
@@ -336,7 +349,10 @@ bringetbitmap(PG_FUNCTION_ARGS)
 									   &off, &size, BUFFER_LOCK_SHARE);
 		if (tup)
 		{
-			tup = brin_copy_tuple(tup, size);
+			if(size <= tupInitSize)
+				memcpy(btup, tup, size);
+			else
+				btup = brin_copy_tuple(tup, size);
 			LockBuffer(buf, BUFFER_LOCK_UNLOCK);
 		}
 
@@ -344,7 +360,7 @@ bringetbitmap(PG_FUNCTION_ARGS)
 		 * For page ranges with no indexed tuple, we must return the whole
 		 * range; otherwise, compare it to the scan keys.
 		 */
-		if (tup == NULL)
+		if (btup == NULL)
 		{
 			addrange = true;
 		}
@@ -352,7 +368,7 @@ bringetbitmap(PG_FUNCTION_ARGS)
 		{
 			BrinMemTuple *dtup;
 
-			dtup = brin_deform_tuple(bdesc, tup);
+			dtup = brin_deform_tuple(bdesc, btup, values, allnulls, hasnulls);
 			if (dtup->bt_placeholder)
 			{
 				/*
@@ -1136,7 +1152,7 @@ union_tuples(BrinDesc *bdesc, BrinMemTuple *a, BrinTuple *b)
 								ALLOCSET_DEFAULT_INITSIZE,
 								ALLOCSET_DEFAULT_MAXSIZE);
 	oldcxt = MemoryContextSwitchTo(cxt);
-	db = brin_deform_tuple(bdesc, b);
+	db = brin_deform_tuple(bdesc, b, NULL, NULL, NULL);
 	MemoryContextSwitchTo(oldcxt);
 
 	for (keyno = 0; keyno < bdesc->bd_tupdesc->natts; keyno++)
diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
index 5a7462b..2f416f1 100644
--- a/src/backend/access/brin/brin_tuple.c
+++ b/src/backend/access/brin/brin_tuple.c
@@ -397,7 +397,8 @@ brin_memtuple_initialize(BrinMemTuple *dtuple, BrinDesc *brdesc)
  * deconstruct the tuple from the on-disk format.
  */
 BrinMemTuple *
-brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple)
+brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple, 
+                  Datum *valuesArg, bool *allnullsArg, bool *hasnullsArg)
 {
 	BrinMemTuple *dtup;
 	Datum	   *values;
@@ -415,9 +416,20 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple)
 		dtup->bt_placeholder = true;
 	dtup->bt_blkno = tuple->bt_blkno;
 
-	values = palloc(sizeof(Datum) * brdesc->bd_totalstored);
-	allnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts);
-	hasnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts);
+	if(!valuesArg)
+	{
+		Assert(!allnullsArg && !hasnullsArg);
+		values = palloc(sizeof(Datum) * brdesc->bd_totalstored);
+		allnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts);
+		hasnulls = palloc(sizeof(bool) * brdesc->bd_tupdesc->natts);
+	}
+	else
+	{
+		Assert(allnullsArg && hasnullsArg);
+		values = valuesArg;
+		allnulls = allnullsArg;
+		hasnulls = hasnullsArg;
+	}
 
 	tp = (char *) tuple + BrinTupleDataOffset(tuple);
 
@@ -460,9 +472,12 @@ brin_deform_tuple(BrinDesc *brdesc, BrinTuple *tuple)
 
 	MemoryContextSwitchTo(oldcxt);
 
-	pfree(values);
-	pfree(allnulls);
-	pfree(hasnulls);
+	if(!valuesArg)
+	{
+		pfree(values);
+		pfree(allnulls);
+		pfree(hasnulls);
+	}
 
 	return dtup;
 }
diff --git a/src/include/access/brin_tuple.h b/src/include/access/brin_tuple.h
index ce63b30..b63ea15 100644
--- a/src/include/access/brin_tuple.h
+++ b/src/include/access/brin_tuple.h
@@ -91,6 +91,9 @@ extern BrinMemTuple *brin_new_memtuple(BrinDesc *brdesc);
 extern void brin_memtuple_initialize(BrinMemTuple *dtuple,
 						 BrinDesc *brdesc);
 extern BrinMemTuple *brin_deform_tuple(BrinDesc *brdesc,
-				  BrinTuple *tuple);
+				  BrinTuple *tuple,
+				  Datum *valuesArg, 
+				  bool *allnullsArg, 
+				  bool *hasnullsArg);
 
 #endif   /* BRIN_TUPLE_H */