add dirty pages
authorCΓ©dric Villemain <cedric@2ndquadrant.fr>
Thu, 20 Feb 2014 23:48:04 +0000 (00:48 +0100)
committerCΓ©dric Villemain <cedric@2ndquadrant.fr>
Mon, 17 Mar 2014 18:06:14 +0000 (19:06 +0100)
pgfincore.c
pgfincore.sql

index 9969a4cdcafd6234f01667131991b02918ba0396..3fddd1222d7c84b18054cdc5cc72a6f59ec84f5a 100644 (file)
@@ -50,7 +50,11 @@ PG_MODULE_MAGIC;
 #define PGSYSCONF_COLS                 3
 #define PGFADVISE_COLS                 4
 #define PGFADVISE_LOADER_COLS  5
+#ifndef HAVE_FINCORE
 #define PGFINCORE_COLS                 8
+#else
+#define PGFINCORE_COLS                 10
+#endif
 
 #define PGF_WILLNEED   10
 #define PGF_DONTNEED   20
@@ -58,6 +62,9 @@ PG_MODULE_MAGIC;
 #define PGF_SEQUENTIAL 40
 #define PGF_RANDOM             50
 
+#define FINCORE_PRESENT 0x1
+#define FINCORE_DIRTY   0x2
+
 /*
  * pgfadvise_fctx structure is needed
  * to keep track of relation path, segment number, ...
@@ -118,6 +125,10 @@ typedef struct
        size_t  rel_os_pages;
        size_t  pages_mem;
        size_t  group_mem;
+#ifdef HAVE_FINCORE
+       size_t  pages_dirty;
+       size_t  group_dirty;
+#endif
        VarBit  *databit;
 } pgfincoreStruct;
 
@@ -736,6 +747,9 @@ static int
 pgfincore_file(char *filename, pgfincoreStruct *pgfncr)
 {
        int             flag=1;
+#ifdef HAVE_FINCORE
+       int             flag_dirty=1;
+#endif
 
        int             len, bitlen;
        bits8   *r;
@@ -765,6 +779,10 @@ pgfincore_file(char *filename, pgfincoreStruct *pgfncr)
         */
        pgfncr->pages_mem               = 0;
        pgfncr->group_mem               = 0;
+#ifdef HAVE_FINCORE
+       pgfncr->pages_dirty             = 0;
+       pgfncr->group_dirty             = 0;
+#endif
        pgfncr->rel_os_pages    = 0;
 
        /*
@@ -830,7 +848,11 @@ pgfincore_file(char *filename, pgfincoreStruct *pgfncr)
                /*
                 * prepare the bit string
                 */
+#ifndef HAVE_FINCORE
                bitlen = (st.st_size+pgfncr->pageSize-1)/pgfncr->pageSize;
+#else
+               bitlen = 2 * ((st.st_size+pgfncr->pageSize-1)/pgfncr->pageSize);
+#endif
                len = VARBITTOTALLEN(bitlen);
                /*
                 * set to 0 so that *r is always initialised and string is zero-padded
@@ -847,10 +869,23 @@ pgfincore_file(char *filename, pgfincoreStruct *pgfncr)
                for (pageIndex = 0; pageIndex <= pgfncr->rel_os_pages; pageIndex++)
                {
                        // block in memory
-                       if (vec[pageIndex] & 1)
+                       if (vec[pageIndex] & FINCORE_PRESENT)
                        {
                                pgfncr->pages_mem++;
                                *r |= x;
+#ifdef HAVE_FINCORE
+                               if (vec[pageIndex] & FINCORE_DIRTY)
+                               {
+                                 pgfncr->pages_dirty++;
+                                 *r |= (x >> 1);
+                                 /* we flag to detect contigous blocks in the same state */
+                                 if (flag_dirty)
+                                       pgfncr->group_dirty++;
+                                 flag_dirty = 0;
+                               }
+                               else
+                                 flag_dirty = 1;
+#endif
                                elog (DEBUG5, "in memory blocks : %lld / %lld",
                                      (long long int) pageIndex, (long long int) pgfncr->rel_os_pages);
 
@@ -862,7 +897,11 @@ pgfincore_file(char *filename, pgfincoreStruct *pgfncr)
                        else
                                flag=1;
 
+
                        x >>= 1;
+#ifdef HAVE_FINCORE
+                       x >>= 1;
+#endif
                        if (x == 0)
                        {
                                x = HIGHBIT;
@@ -1038,6 +1077,12 @@ pgfincore(PG_FUNCTION_ARGS)
                        nulls[7]  = true;
                        values[7] = (Datum) NULL;
                }
+#ifdef HAVE_FINCORE
+               /* number of pages dirty in OS cache */
+               values[8] = Int64GetDatum(pgfncr->pages_dirty);
+               /* number of group of contigous dirty pages in os cache */
+               values[9] = Int64GetDatum(pgfncr->group_dirty);
+#endif
                /* Build the result tuple. */
                tuple = heap_form_tuple(fctx->tupd, values, nulls);
 
index 06116b38146c02664f48180a3f7833b1f917b18d..6268ef5241f00899a9f5f599b6ef9cffadad23a6 100644 (file)
@@ -122,7 +122,9 @@ pgfincore(IN regclass, IN text, IN bool,
                  OUT pages_mem bigint,
                  OUT group_mem bigint,
                  OUT os_pages_free bigint,
-                 OUT databit      varbit)
+                 OUT databit      varbit,
+                 OUT pages_dirty bigint,
+                 OUT group_dirty bigint)
 RETURNS setof record
 AS '$libdir/pgfincore'
 LANGUAGE C;
@@ -136,7 +138,9 @@ pgfincore(IN regclass, IN bool,
                  OUT pages_mem bigint,
                  OUT group_mem bigint,
                  OUT os_pages_free bigint,
-                 OUT databit      varbit)
+                 OUT databit      varbit,
+                 OUT pages_dirty bigint,
+                 OUT group_dirty bigint)
 RETURNS setof record
 AS 'SELECT * from pgfincore($1, ''main'', $2)'
 LANGUAGE SQL;
@@ -150,7 +154,9 @@ pgfincore(IN regclass,
                  OUT pages_mem bigint,
                  OUT group_mem bigint,
                  OUT os_pages_free bigint,
-                 OUT databit      varbit)
+                 OUT databit      varbit,
+                 OUT pages_dirty bigint,
+                 OUT group_dirty bigint)
 RETURNS setof record
 AS 'SELECT * from pgfincore($1, ''main'', false)'
 LANGUAGE SQL;