1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2025-07-05 00:28:52 +02:00

Add cvtZSubNTo*() functions.

These functions allow conversion from substrings without needing to create a String or a temporary buffer.

httpDateToTime() no longer requires a temp mem context. Also improve handling of month search to avoid an allocation.

httpUriDecode() no longer requires a temp mem context.

jsonReadStr() no longer requires a temp mem context.

pgLsnFromWalSegment() no longer requires a temp mem context.

pgVersionFromStr() no longer requires a temp mem context. Also do a bit of refactoring.

storageGcsCvtTime() no longer leaks six Strings per call.

storageS3CvtTime() no longer leaks six Strings per call.
This commit is contained in:
David Steele
2022-04-28 09:50:23 -04:00
parent 6e18235be8
commit bc46d4e37b
12 changed files with 273 additions and 202 deletions

View File

@ -509,17 +509,10 @@ pgLsnFromWalSegment(const String *const walSegment, const unsigned int walSegmen
ASSERT(strSize(walSegment) == 24);
ASSERT(walSegmentSize > 0);
uint64_t result;
MEM_CONTEXT_TEMP_BEGIN()
{
result =
(cvtZToUInt64Base(strZ(strSubN(walSegment, 8, 8)), 16) << 32) +
(cvtZToUInt64Base(strZ(strSubN(walSegment, 16, 8)), 16) * walSegmentSize);
}
MEM_CONTEXT_TEMP_END();
FUNCTION_TEST_RETURN(UINT64, result);
FUNCTION_TEST_RETURN(
UINT64,
(cvtZSubNToUInt64Base(strZ(walSegment), 8, 8, 16) << 32) +
(cvtZSubNToUInt64Base(strZ(walSegment), 16, 8, 16) * walSegmentSize));
}
/**********************************************************************************************************************************/
@ -533,12 +526,7 @@ pgTimelineFromWalSegment(const String *const walSegment)
ASSERT(walSegment != NULL);
ASSERT(strSize(walSegment) == 24);
char buffer[9];
strncpy(buffer, strZ(walSegment), sizeof(buffer) - 1);
buffer[sizeof(buffer) - 1] = '\0';
FUNCTION_TEST_RETURN(UINT32, cvtZToUIntBase(buffer, 16));
FUNCTION_TEST_RETURN(UINT32, cvtZSubNToUIntBase(strZ(walSegment), 0, 8, 16));
}
/**********************************************************************************************************************************/
@ -646,7 +634,7 @@ pgXactPath(unsigned int pgVersion)
/**********************************************************************************************************************************/
unsigned int
pgVersionFromStr(const String *version)
pgVersionFromStr(const String *const version)
{
FUNCTION_LOG_BEGIN(logLevelTrace);
FUNCTION_LOG_PARAM(STRING, version);
@ -654,33 +642,19 @@ pgVersionFromStr(const String *version)
ASSERT(version != NULL);
unsigned int result = 0;
// If format not number.number (9.4) or number only (10) then error. No check for valid/supported PG version is on purpose.
if (!regExpMatchOne(STRDEF("^[0-9]+[.]*[0-9]+$"), version))
THROW_FMT(AssertError, "version %s format is invalid", strZ(version));
MEM_CONTEXT_TEMP_BEGIN()
{
// If format is not number.number (9.4) or number only (10) then error
if (!regExpMatchOne(STRDEF("^[0-9]+[.]*[0-9]+$"), version))
THROW_FMT(AssertError, "version %s format is invalid", strZ(version));
// If there is no dot then only the major version is needed
const int idxStart = strChr(version, '.');
// If there is a dot set the major and minor versions, else just the major
int idxStart = strChr(version, '.');
unsigned int major;
unsigned int minor = 0;
if (idxStart == -1)
FUNCTION_LOG_RETURN(UINT, cvtZToUInt(strZ(version)) * 10000);
if (idxStart != -1)
{
major = cvtZToUInt(strZ(strSubN(version, 0, (size_t)idxStart)));
minor = cvtZToUInt(strZ(strSub(version, (size_t)idxStart + 1)));
}
else
major = cvtZToUInt(strZ(version));
// No check to see if valid/supported PG version is on purpose
result = major * 10000 + minor * 100;
}
MEM_CONTEXT_TEMP_END();
FUNCTION_LOG_RETURN(UINT, result);
// Major and minor version are needed
FUNCTION_LOG_RETURN(
UINT, cvtZSubNToUInt(strZ(version), 0, (size_t)idxStart) * 10000 + cvtZToUInt(strZ(version) + (size_t)idxStart + 1) * 100);
}
String *