Add FreePageManagerInquireLargest.
authorRobert Haas <rhaas@postgresql.org>
Wed, 12 Mar 2014 17:25:40 +0000 (13:25 -0400)
committerRobert Haas <rhaas@postgresql.org>
Wed, 12 Mar 2014 17:25:40 +0000 (13:25 -0400)
contrib/test_freepage/test_freepage--1.0.sql
contrib/test_freepage/test_freepage.c
src/backend/utils/mmgr/freepage.c
src/include/utils/freepage.h

index 490c662dcaa574aad654c5abdb23e9c0a75b9a59..5d3191e88ba6cecba90781f65fc81e57bf51b611 100644 (file)
@@ -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
index 9aea03a813ea65b66144af5870242e0697796094..074cf56891881ffba67ceacc5701d2421c616fc1 100644 (file)
 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)
 {
index 2c1845a79ba4b289fc10a2b6e5ecac3aae0da344..87fbfb8841b74e08585415c2892be19f31d2020b 100644 (file)
@@ -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.
  */
index 51ba40a84d771c86d28fbece7ff4c216f4752dd6..df25464c1ee93827b6b4c989e3eb7e1da420ac32 100644 (file)
@@ -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 */