From 0207ea0cf1350b7db12441c7073b81995ebc27e3 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Wed, 12 Mar 2014 13:25:40 -0400 Subject: [PATCH] Add FreePageManagerInquireLargest. --- contrib/test_freepage/test_freepage--1.0.sql | 2 + contrib/test_freepage/test_freepage.c | 11 +++++ src/backend/utils/mmgr/freepage.c | 44 ++++++++++++++++++++ src/include/utils/freepage.h | 1 + 4 files changed, 58 insertions(+) diff --git a/contrib/test_freepage/test_freepage--1.0.sql b/contrib/test_freepage/test_freepage--1.0.sql index 490c662dca..5d3191e88b 100644 --- a/contrib/test_freepage/test_freepage--1.0.sql +++ b/contrib/test_freepage/test_freepage--1.0.sql @@ -7,6 +7,8 @@ CREATE FUNCTION init(size pg_catalog.int8) RETURNS pg_catalog.void AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FUNCTION get(pages pg_catalog.int8) RETURNS pg_catalog.int8 AS 'MODULE_PATHNAME' LANGUAGE C STRICT; +CREATE FUNCTION inquire_largest() RETURNS pg_catalog.int8 + AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FUNCTION put(first_page pg_catalog.int8, npages pg_catalog.int8) RETURNS pg_catalog.void AS 'MODULE_PATHNAME' LANGUAGE C STRICT; CREATE FUNCTION dump() RETURNS pg_catalog.text diff --git a/contrib/test_freepage/test_freepage.c b/contrib/test_freepage/test_freepage.c index 9aea03a813..074cf56891 100644 --- a/contrib/test_freepage/test_freepage.c +++ b/contrib/test_freepage/test_freepage.c @@ -21,11 +21,13 @@ PG_MODULE_MAGIC; PG_FUNCTION_INFO_V1(init); PG_FUNCTION_INFO_V1(get); +PG_FUNCTION_INFO_V1(inquire_largest); PG_FUNCTION_INFO_V1(put); PG_FUNCTION_INFO_V1(dump); Datum init(PG_FUNCTION_ARGS); Datum get(PG_FUNCTION_ARGS); +Datum inquire_largest(PG_FUNCTION_ARGS); Datum put(PG_FUNCTION_ARGS); Datum dump(PG_FUNCTION_ARGS); @@ -81,6 +83,15 @@ get(PG_FUNCTION_ARGS) PG_RETURN_INT64(first_page); } +Datum +inquire_largest(PG_FUNCTION_ARGS) +{ + if (fpm == NULL) + PG_RETURN_NULL(); + + PG_RETURN_INT64(FreePageManagerInquireLargest(fpm)); +} + Datum put(PG_FUNCTION_ARGS) { diff --git a/src/backend/utils/mmgr/freepage.c b/src/backend/utils/mmgr/freepage.c index 2c1845a79b..87fbfb8841 100644 --- a/src/backend/utils/mmgr/freepage.c +++ b/src/backend/utils/mmgr/freepage.c @@ -183,6 +183,50 @@ FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page) return result; } +/* + * Return the size of the largest run of pages that the user could + * succesfully get. + */ +Size +FreePageManagerInquireLargest(FreePageManager *fpm) +{ + LWLock *lock = fpm_lock(fpm); + char *base = fpm_segment_base(fpm); + Size largest = 0; + + if (lock != NULL) + LWLockAcquire(lock, LW_EXCLUSIVE); + + if (!relptr_is_null(fpm->freelist[FPM_NUM_FREELISTS - 1])) + { + FreePageSpanLeader *candidate; + + candidate = relptr_access(base, fpm->freelist[FPM_NUM_FREELISTS - 1]); + do + { + if (candidate->npages > largest) + largest = candidate->npages; + candidate = relptr_access(base, candidate->next); + } while (candidate != NULL); + } + else + { + Size f = FPM_NUM_FREELISTS - 1; + + do + { + --f; + if (!relptr_is_null(fpm->freelist[f])) + largest = f + 1; + } while (f > 0); + } + + if (lock != NULL) + LWLockRelease(lock); + + return largest; +} + /* * Transfer a run of pages to the free page manager. */ diff --git a/src/include/utils/freepage.h b/src/include/utils/freepage.h index 51ba40a84d..df25464c1e 100644 --- a/src/include/utils/freepage.h +++ b/src/include/utils/freepage.h @@ -90,6 +90,7 @@ extern bool FreePageManagerGet(FreePageManager *fpm, Size npages, Size *first_page); extern void FreePageManagerPut(FreePageManager *fpm, Size first_page, Size npages); +extern Size FreePageManagerInquireLargest(FreePageManager *fpm); extern char *FreePageManagerDump(FreePageManager *fpm); #endif /* FREEPAGE_H */ -- 2.39.5