Cache the most recent region lookup.
authorRobert Haas <rhaas@postgresql.org>
Fri, 13 Jun 2014 16:24:21 +0000 (16:24 +0000)
committerRobert Haas <rhaas@postgresql.org>
Fri, 13 Jun 2014 16:24:21 +0000 (16:24 +0000)
The general value of this is debatable, because access could be pretty
random across a large number of regions.  But the sort code, for example,
likes to ask about chunks of memory that were just recently allocated
or are about to be freed, so this will help there, too.  And it helps
a lot if someone (say) builds a linked list and then frees the elements
in order.

src/backend/utils/mmgr/aregion.c

index 9ba2ece4847bc0edd47e118704ae6b634eb26e1a..a9483a71576fdf905e8dae9fc0171a12992833ae 100644 (file)
@@ -80,6 +80,9 @@ static AllocatorRegionLookupRoot lookup_root;
 static AllocatorRegionLookupLeaf lookup_root_leaf;
 #endif
 
+/* Single-entry cache for the most recently looked-up region. */
+static AllocatorRegion *most_recent_region;
+
 /*
  * Backend-private chunks binned by maximum contiguous freespace.  Lists are
  * doubly-linked using fl_node.  List 0 contains regions with no internal
@@ -217,6 +220,13 @@ LookupAllocatorRegion(void *ptr)
        AllocatorRegionLookupLeaf *leaf = NULL;
        int             high, low;
 
+       /* It's pretty common to look up the same region repeatedly. */
+       if (most_recent_region != NULL && 
+               ((char *) ptr) >= most_recent_region->region_start &&
+               ((char *) ptr) < most_recent_region->region_start +
+               most_recent_region->region_size)
+               return most_recent_region;
+
        /*
         * If this is a 64-bit system, locate the lookup table that pertains
         * to the upper 32 bits of ptr.  On a 32-bit system, there's only one
@@ -263,7 +273,10 @@ LookupAllocatorRegion(void *ptr)
                else if (region->region_start + region->region_size < (char *) ptr)
                        low = mid + 1;
                else
+               {
+                       most_recent_region = region;
                        return region;
+               }
        }
 
        return NULL;
@@ -497,6 +510,15 @@ static bool
 AllocatorRegionAdjustLookup(AllocatorRegion *region, bool insert)
 {
        bool    ok = true;
+#if SIZEOF_SIZE_T > 4
+       Size    tabstart;
+       Size    tabstop;
+       Size    i;
+#endif
+
+       /* Flush cache needed. */
+       if (!insert && most_recent_region == region)
+               most_recent_region = NULL;
 
        /*
         * If this is a 64-bit system, we need to loop over all of the relevant
@@ -504,10 +526,6 @@ AllocatorRegionAdjustLookup(AllocatorRegion *region, bool insert)
         * and we simply update that.
         */
 #if SIZEOF_SIZE_T > 4
-       Size    tabstart;
-       Size    tabstop;
-       Size    i;
-
        tabstart = ((Size) region->region_start) >> 32;
        tabstop = ((Size) region->region_start + region->region_size - 1) >> 32;