热点函数替换memcpy_sp和添加inline函数
This commit is contained in:
@ -68,19 +68,6 @@ void FreeStringInfo(StringInfo str)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* resetStringInfo
|
||||
*
|
||||
* Reset the StringInfo: the data buffer remains valid, but its
|
||||
* previous content, if any, is cleared.
|
||||
*/
|
||||
void resetStringInfo(StringInfo str)
|
||||
{
|
||||
str->data[0] = '\0';
|
||||
str->len = 0;
|
||||
str->cursor = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* appendStringInfo
|
||||
*
|
||||
@ -550,22 +537,6 @@ void enlargeBufferSize(int needed, // needed more bytes
|
||||
// template void enlargeBuffer<int>(int, int, int*, char** data);
|
||||
// template void enlargeBuffer<size_t>(int, int, size_t*, char** data);
|
||||
|
||||
/*
|
||||
* enlargeStringInfo
|
||||
*
|
||||
* Make sure there is enough space for StringInfo
|
||||
*
|
||||
* External callers usually need not concern themselves with this, since
|
||||
* all stringinfo.c routines do it automatically. However, if a caller
|
||||
* knows that a StringInfo will eventually become X bytes large, it
|
||||
* can save some palloc overhead by enlarging the buffer before starting
|
||||
* to store data in it.
|
||||
*/
|
||||
void enlargeStringInfo(StringInfo str, int needed)
|
||||
{
|
||||
enlargeBuffer(needed, str->len, &str->maxlen, &str->data);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function is used to request the use of more than 1GB of memory
|
||||
*/
|
||||
|
||||
@ -163,7 +163,7 @@ void pq_sendcountedtext_printtup(StringInfo buf, const char* str, int slen, int
|
||||
slen = strlen(p);
|
||||
enlargeStringInfo(buf, slen + sizeof(uint32));
|
||||
pq_writeint32(buf, (uint32)slen);
|
||||
errno_t rc = memcpy_s(buf->data + buf->len, (size_t)(buf->maxlen - buf->len), p, (size_t)slen);
|
||||
errno_t rc = memcpy_sp(buf->data + buf->len, (size_t)(buf->maxlen - buf->len), p, (size_t)slen);
|
||||
securec_check(rc, "\0", "\0");
|
||||
buf->len += slen;
|
||||
buf->data[buf->len] = '\0';
|
||||
@ -172,7 +172,7 @@ void pq_sendcountedtext_printtup(StringInfo buf, const char* str, int slen, int
|
||||
} else {
|
||||
enlargeStringInfo(buf, slen + sizeof(uint32));
|
||||
pq_writeint32(buf, (uint32)slen);
|
||||
errno_t rc = memcpy_s(buf->data + buf->len, (size_t)(buf->maxlen - buf->len), str, (size_t)slen);
|
||||
errno_t rc = memcpy_sp(buf->data + buf->len, (size_t)(buf->maxlen - buf->len), str, (size_t)slen);
|
||||
securec_check(rc, "\0", "\0");
|
||||
buf->len += slen;
|
||||
buf->data[buf->len] = '\0';
|
||||
@ -317,19 +317,6 @@ void pq_endmessage(StringInfo buf)
|
||||
buf->data = NULL;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
* pq_endmessage_reuse - send the completed message to the frontend
|
||||
*
|
||||
* The data buffer is *not* freed, allowing to reuse the buffer with
|
||||
* pg_beginmessage_reuse.
|
||||
--------------------------------
|
||||
*/
|
||||
void pq_endmessage_reuse(StringInfo buf)
|
||||
{
|
||||
/* msgtype was saved in cursor field */
|
||||
(void)pq_putmessage(buf->cursor, buf->data, buf->len);
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
* pq_endmessage_noblock - Same as pq_endmessage but non-blocking
|
||||
* --------------------------------
|
||||
|
||||
@ -545,9 +545,9 @@ int pg_ultoa_n(uint32 value, char *a)
|
||||
|
||||
value /= 10000;
|
||||
|
||||
errno_t rc = memcpy_s(pos - 2, 2, DIGIT_TABLE + c0, 2);
|
||||
errno_t rc = memcpy_sp(pos - 2, 2, DIGIT_TABLE + c0, 2);
|
||||
securec_check(rc, "\0", "\0");
|
||||
rc = memcpy_s(pos - 4, 2, DIGIT_TABLE + c1, 2);
|
||||
rc = memcpy_sp(pos - 4, 2, DIGIT_TABLE + c1, 2);
|
||||
securec_check(rc, "\0", "\0");
|
||||
i += 4;
|
||||
}
|
||||
@ -558,7 +558,7 @@ int pg_ultoa_n(uint32 value, char *a)
|
||||
|
||||
value /= 100;
|
||||
|
||||
errno_t rc = memcpy_s(pos - 2, 2, DIGIT_TABLE + c, 2);
|
||||
errno_t rc = memcpy_sp(pos - 2, 2, DIGIT_TABLE + c, 2);
|
||||
securec_check(rc, "\0", "\0");
|
||||
i += 2;
|
||||
}
|
||||
@ -567,7 +567,7 @@ int pg_ultoa_n(uint32 value, char *a)
|
||||
|
||||
char *pos = a + olength - i;
|
||||
|
||||
errno_t rc = memcpy_s(pos - 2, 2, DIGIT_TABLE + c, 2);
|
||||
errno_t rc = memcpy_sp(pos - 2, 2, DIGIT_TABLE + c, 2);
|
||||
securec_check(rc, "\0", "\0");
|
||||
} else {
|
||||
*a = (char)('0' + value);
|
||||
@ -633,7 +633,7 @@ char* pg_ultostr_zeropad(char* str, uint32 value, int32 minwidth)
|
||||
|
||||
if (value < 100 && minwidth == 2) /* Short cut for common case */
|
||||
{
|
||||
rc = memcpy_s(str, 2, DIGIT_TABLE + value * 2, 2);
|
||||
rc = memcpy_sp(str, 2, DIGIT_TABLE + value * 2, 2);
|
||||
securec_check(rc, "\0", "\0");
|
||||
return str + 2;
|
||||
}
|
||||
|
||||
@ -483,31 +483,6 @@ void ExecClearMutilTuple(List* slots)
|
||||
(void)ExecClearTuple(slot);
|
||||
}
|
||||
}
|
||||
/* --------------------------------
|
||||
* ExecStoreVirtualTuple
|
||||
* Mark a slot as containing a virtual tuple.
|
||||
*
|
||||
* The protocol for loading a slot with virtual tuple data is:
|
||||
* * Call ExecClearTuple to mark the slot empty.
|
||||
* * Store data into the Datum/isnull arrays.
|
||||
* * Call ExecStoreVirtualTuple to mark the slot valid.
|
||||
* This is a bit unclean but it avoids one round of data copying.
|
||||
* --------------------------------
|
||||
*/
|
||||
TupleTableSlot* ExecStoreVirtualTuple(TupleTableSlot* slot)
|
||||
{
|
||||
/*
|
||||
* sanity checks
|
||||
*/
|
||||
Assert(slot != NULL);
|
||||
Assert(slot->tts_tupleDescriptor != NULL);
|
||||
Assert(TTS_EMPTY(slot));
|
||||
|
||||
slot->tts_flags &= ~TTS_FLAG_EMPTY;
|
||||
slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
/* --------------------------------
|
||||
* ExecStoreAllNullTuple
|
||||
|
||||
@ -66,7 +66,7 @@ static inline void ReleaseNodeVMBuffer(IndexOnlyScanState* node)
|
||||
* ExecGPIGetNextPartRelation
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
bool ExecGPIGetNextPartRelation(IndexOnlyScanState* node, IndexScanDesc indexScan)
|
||||
inline bool ExecGPIGetNextPartRelation(IndexOnlyScanState* node, IndexScanDesc indexScan)
|
||||
{
|
||||
if (IndexScanNeedSwitchPartRel(indexScan)) {
|
||||
/* Release VM buffer pin, if any. */
|
||||
@ -334,7 +334,7 @@ static bool IndexOnlyRecheck(IndexOnlyScanState* node, TupleTableSlot* slot)
|
||||
* ExecIndexOnlyScan(node)
|
||||
* ----------------------------------------------------------------
|
||||
*/
|
||||
static TupleTableSlot* ExecIndexOnlyScan(PlanState* state)
|
||||
static inline TupleTableSlot* ExecIndexOnlyScan(PlanState* state)
|
||||
{
|
||||
IndexOnlyScanState* node = castNode(IndexOnlyScanState, state);
|
||||
/*
|
||||
|
||||
@ -2431,7 +2431,7 @@ bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, S
|
||||
|
||||
/* check for bogus TID */
|
||||
if (offnum < FirstOffsetNumber || offnum > PageGetMaxOffsetNumber(dp)) {
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
lp = PageGetItemId(dp, offnum);
|
||||
@ -2445,7 +2445,7 @@ bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, S
|
||||
continue;
|
||||
}
|
||||
/* else must be end of chain */
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2468,7 +2468,7 @@ bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, S
|
||||
* Shouldn't see a HEAP_ONLY tuple at chain start.
|
||||
*/
|
||||
if (at_chain_start && HeapTupleIsHeapOnly(heap_tuple)) {
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2476,7 +2476,7 @@ bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, S
|
||||
* broken.
|
||||
*/
|
||||
if (TransactionIdIsValid(prev_xmax) && !TransactionIdEquals(prev_xmax, HeapTupleGetRawXmin(heap_tuple))) {
|
||||
break;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2557,7 +2557,7 @@ bool heap_hot_search_buffer(ItemPointer tid, Relation relation, Buffer buffer, S
|
||||
at_chain_start = false;
|
||||
prev_xmax = HeapTupleGetUpdateXid(heap_tuple);
|
||||
} else {
|
||||
break; /* end of chain */
|
||||
return false; /* end of chain */
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@ -1852,7 +1852,7 @@ bool _bt_check_natts(const Relation index, bool heapkeyspace, Page page, OffsetN
|
||||
return num_tuple_attrs > 0 && num_tuple_attrs <= nkeyatts;
|
||||
}
|
||||
|
||||
static int btree_setup_posting_items(BTScanOpaque so, int item_idx, OffsetNumber offnum, ItemPointer heap_tid,
|
||||
static inline int btree_setup_posting_items(BTScanOpaque so, int item_idx, OffsetNumber offnum, ItemPointer heap_tid,
|
||||
IndexTuple tuple)
|
||||
{
|
||||
BTScanPosItem *curr_item = &so->currPos.items[item_idx];
|
||||
@ -1878,7 +1878,7 @@ static int btree_setup_posting_items(BTScanOpaque so, int item_idx, OffsetNumber
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void btree_save_posting_item(BTScanOpaque so, int item_idx, OffsetNumber offnum, ItemPointer heap_tid,
|
||||
static inline void btree_save_posting_item(BTScanOpaque so, int item_idx, OffsetNumber offnum, ItemPointer heap_tid,
|
||||
int tuple_offset)
|
||||
{
|
||||
BTScanPosItem *curr_item = &so->currPos.items[item_idx];
|
||||
|
||||
@ -196,7 +196,33 @@ extern TupleTableSlot* ExecStoreDataRowTuple(
|
||||
#endif
|
||||
extern TupleTableSlot* ExecClearTuple(TupleTableSlot* slot);
|
||||
extern void ExecClearMutilTuple(List* slots);
|
||||
extern TupleTableSlot* ExecStoreVirtualTuple(TupleTableSlot* slot);
|
||||
|
||||
/* --------------------------------
|
||||
* ExecStoreVirtualTuple
|
||||
* Mark a slot as containing a virtual tuple.
|
||||
*
|
||||
* The protocol for loading a slot with virtual tuple data is:
|
||||
* * Call ExecClearTuple to mark the slot empty.
|
||||
* * Store data into the Datum/isnull arrays.
|
||||
* * Call ExecStoreVirtualTuple to mark the slot valid.
|
||||
* This is a bit unclean but it avoids one round of data copying.
|
||||
* --------------------------------
|
||||
*/
|
||||
inline TupleTableSlot* ExecStoreVirtualTuple(TupleTableSlot* slot)
|
||||
{
|
||||
/*
|
||||
* sanity checks
|
||||
*/
|
||||
Assert(slot != NULL);
|
||||
Assert(slot->tts_tupleDescriptor != NULL);
|
||||
Assert(TTS_EMPTY(slot));
|
||||
|
||||
slot->tts_flags &= ~TTS_FLAG_EMPTY;
|
||||
slot->tts_nvalid = slot->tts_tupleDescriptor->natts;
|
||||
|
||||
return slot;
|
||||
}
|
||||
|
||||
extern TupleTableSlot* ExecStoreAllNullTuple(TupleTableSlot* slot);
|
||||
extern HeapTuple ExecCopySlotTuple(TupleTableSlot* slot);
|
||||
extern MinimalTuple ExecCopySlotMinimalTuple(TupleTableSlot* slot, bool need_transform_anyarray = false);
|
||||
|
||||
@ -93,7 +93,12 @@ extern void initStringInfo(StringInfo str);
|
||||
* Clears the current content of the StringInfo, if any. The
|
||||
* StringInfo remains valid.
|
||||
*/
|
||||
extern void resetStringInfo(StringInfo str);
|
||||
inline void resetStringInfo(StringInfo str)
|
||||
{
|
||||
str->data[0] = '\0';
|
||||
str->len = 0;
|
||||
str->cursor = 0;
|
||||
}
|
||||
|
||||
/* ------------------------
|
||||
* appendStringInfo
|
||||
@ -147,10 +152,26 @@ extern void appendStringInfoChar(StringInfo str, char ch);
|
||||
extern void appendBinaryStringInfo(StringInfo str, const char* data, int datalen);
|
||||
|
||||
/* ------------------------
|
||||
* enlargeStringInfo
|
||||
* Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
|
||||
* enlargeBuffer
|
||||
* Make sure a buffer can hold at least 'needed' more bytes.
|
||||
*/
|
||||
extern void enlargeStringInfo(StringInfo str, int needed);
|
||||
void enlargeBuffer(int needed, int len, int* maxlen, char** data);
|
||||
|
||||
/* ------------------------
|
||||
* enlargeStringInfo
|
||||
*
|
||||
* Make sure there is enough space for StringInfo
|
||||
*
|
||||
* External callers usually need not concern themselves with this, since
|
||||
* all stringinfo.c routines do it automatically. However, if a caller
|
||||
* knows that a StringInfo will eventually become X bytes large, it
|
||||
* can save some palloc overhead by enlarging the buffer before starting
|
||||
* to store data in it.
|
||||
*/
|
||||
inline void enlargeStringInfo(StringInfo str, int needed)
|
||||
{
|
||||
enlargeBuffer(needed, str->len, &str->maxlen, &str->data);
|
||||
}
|
||||
|
||||
/* -----------------------
|
||||
* dupStringInfo
|
||||
|
||||
@ -87,7 +87,12 @@ extern void FreeStringInfo(StringInfo str);
|
||||
* Clears the current content of the StringInfo, if any. The
|
||||
* StringInfo remains valid.
|
||||
*/
|
||||
extern void resetStringInfo(StringInfo str);
|
||||
inline void resetStringInfo(StringInfo str)
|
||||
{
|
||||
str->data[0] = '\0';
|
||||
str->len = 0;
|
||||
str->cursor = 0;
|
||||
}
|
||||
|
||||
/* ------------------------
|
||||
* appendStringInfo
|
||||
@ -166,9 +171,19 @@ void enlargeBufferSize(int needed, int len, size_t* maxlen, char** data);
|
||||
|
||||
/* ------------------------
|
||||
* enlargeStringInfo
|
||||
* Make sure a StringInfo's buffer can hold at least 'needed' more bytes.
|
||||
*
|
||||
* Make sure there is enough space for StringInfo
|
||||
*
|
||||
* External callers usually need not concern themselves with this, since
|
||||
* all stringinfo.c routines do it automatically. However, if a caller
|
||||
* knows that a StringInfo will eventually become X bytes large, it
|
||||
* can save some palloc overhead by enlarging the buffer before starting
|
||||
* to store data in it.
|
||||
*/
|
||||
extern void enlargeStringInfo(StringInfo str, int needed);
|
||||
inline void enlargeStringInfo(StringInfo str, int needed)
|
||||
{
|
||||
enlargeBuffer(needed, str->len, &str->maxlen, &str->data);
|
||||
}
|
||||
|
||||
/*
|
||||
* The following function is used to request the use of more than 1GB of memory
|
||||
|
||||
@ -28,8 +28,9 @@ extern void pq_send_ascii_string(StringInfo buf, const char* str);
|
||||
extern void pq_sendfloat4(StringInfo buf, float4 f);
|
||||
extern void pq_sendfloat8(StringInfo buf, float8 f);
|
||||
extern void pq_endmessage(StringInfo buf);
|
||||
extern void pq_endmessage_reuse(StringInfo buf);
|
||||
extern void pq_endmessage_noblock(StringInfo buf);
|
||||
extern int pq_putmessage(char msgtype, const char* s, size_t len);
|
||||
|
||||
|
||||
extern void pq_begintypsend(StringInfo buf);
|
||||
extern bytea* pq_endtypsend(StringInfo buf);
|
||||
@ -51,6 +52,19 @@ extern char* pq_getmsgtext(StringInfo msg, int rawbytes, int* nbytes);
|
||||
extern const char* pq_getmsgstring(StringInfo msg);
|
||||
extern void pq_getmsgend(StringInfo msg);
|
||||
|
||||
/* --------------------------------
|
||||
* pq_endmessage_reuse - send the completed message to the frontend
|
||||
*
|
||||
* The data buffer is *not* freed, allowing to reuse the buffer with
|
||||
* pg_beginmessage_reuse.
|
||||
--------------------------------
|
||||
*/
|
||||
inline void pq_endmessage_reuse(StringInfo buf)
|
||||
{
|
||||
/* msgtype was saved in cursor field */
|
||||
(void)pq_putmessage(buf->cursor, buf->data, buf->len);
|
||||
}
|
||||
|
||||
static inline uint128 pg_bswap128(uint128 x)
|
||||
{
|
||||
return
|
||||
@ -125,7 +139,7 @@ static inline void pq_writeint32(StringInfoData* pg_restrict buf, uint32 i)
|
||||
uint32 ni = htonl(i);
|
||||
errno_t rc = EOK;
|
||||
|
||||
rc = memcpy_s((char* pg_restrict)(buf->data + buf->len), sizeof(uint32), &ni, sizeof(uint32));
|
||||
rc = memcpy_sp((char* pg_restrict)(buf->data + buf->len), sizeof(uint32), &ni, sizeof(uint32));
|
||||
securec_check(rc, "\0", "\0");
|
||||
buf->len += sizeof(uint32);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user