diff --git a/doc/xml/release.xml b/doc/xml/release.xml index a512577a1..14363868f 100644 --- a/doc/xml/release.xml +++ b/doc/xml/release.xml @@ -118,6 +118,14 @@

Inline strPtr() to increase profiling accuracy.

+ + + + + + +

Add pgLsnFromWalSegment().

+
diff --git a/src/postgres/interface.c b/src/postgres/interface.c index e1ac097ff..6699dfe0c 100644 --- a/src/postgres/interface.c +++ b/src/postgres/interface.c @@ -627,6 +627,23 @@ pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize) strNewFmt("%08X%08X%08X", timeline, (unsigned int)(lsn >> 32), (unsigned int)(lsn & 0xFFFFFFFF) / walSegmentSize)); } +uint64_t +pgLsnFromWalSegment(const String *walSegment, unsigned int walSegmentSize) +{ + FUNCTION_TEST_BEGIN(); + FUNCTION_TEST_PARAM(STRING, walSegment); + FUNCTION_TEST_PARAM(UINT, walSegmentSize); + FUNCTION_TEST_END(); + + ASSERT(walSegment != NULL); + ASSERT(strSize(walSegment) == 24); + ASSERT(walSegmentSize > 0); + + FUNCTION_TEST_RETURN( + (cvtZToUInt64Base(strPtr(strSubN(walSegment, 8, 8)), 16) << 32) + + (cvtZToUInt64Base(strPtr(strSubN(walSegment, 16, 8)), 16) * walSegmentSize)); +} + /**********************************************************************************************************************************/ StringList * pgLsnRangeToWalSegmentList( diff --git a/src/postgres/interface.h b/src/postgres/interface.h index ffc291225..05d8d0b32 100644 --- a/src/postgres/interface.h +++ b/src/postgres/interface.h @@ -137,8 +137,9 @@ String *pgTablespaceId(unsigned int pgVersion); uint64_t pgLsnFromStr(const String *lsn); String *pgLsnToStr(uint64_t lsn); -// Convert a timeline and lsn to a wal segment +// Convert a timeline and lsn to a wal segment and vice versa String *pgLsnToWalSegment(uint32_t timeline, uint64_t lsn, unsigned int walSegmentSize); +uint64_t pgLsnFromWalSegment(const String *walSegment, unsigned int walSegmentSize); // Convert a timeline and lsn range to a list of wal segments StringList *pgLsnRangeToWalSegmentList( diff --git a/test/src/module/postgres/interfaceTest.c b/test/src/module/postgres/interfaceTest.c index 0eb8d7e8d..ee71b964e 100644 --- a/test/src/module/postgres/interfaceTest.c +++ b/test/src/module/postgres/interfaceTest.c @@ -105,7 +105,7 @@ testRun(void) } // ***************************************************************************************************************************** - if (testBegin("pgLsnFromStr(), pgLsnToStr(), pgLsnToWalSegment(), and pgLsnRangeToWalSegmentList()")) + if (testBegin("pgLsnFromStr(), pgLsnToStr(), pgLsnToWalSegment(), pgLsnFromWalSegment(), and pgLsnRangeToWalSegmentList()")) { TEST_RESULT_UINT(pgLsnFromStr(STRDEF("1/1")), 0x0000000100000001, "lsn to string"); TEST_RESULT_UINT(pgLsnFromStr(STRDEF("ffffffff/ffffffff")), 0xFFFFFFFFFFFFFFFF, "lsn to string"); @@ -119,6 +119,13 @@ testRun(void) TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFFAAAAAAAA, 0x40000000), "00000001FFFFFFFF00000002", "lsn to wal segment"); TEST_RESULT_STR_Z(pgLsnToWalSegment(1, 0xFFFFFFFF40000000, 0x40000000), "00000001FFFFFFFF00000001", "lsn to wal segment"); + TEST_RESULT_UINT( + pgLsnFromWalSegment(STRDEF("00000001FFFFFFFF000000AA"), 0x1000000), 0xFFFFFFFFAA000000, "16M wal segment to lsn"); + TEST_RESULT_UINT( + pgLsnFromWalSegment(STRDEF("00000001FFFFFFFF00000002"), 0x40000000), 0xFFFFFFFF80000000, "1G wal segment to lsn"); + TEST_RESULT_UINT( + pgLsnFromWalSegment(STRDEF("00000001FFFFFFFF00000001"), 0x40000000), 0xFFFFFFFF40000000, "1G wal segment to lsn"); + TEST_RESULT_STR_Z( strLstJoin( pgLsnRangeToWalSegmentList(