Re: reducing the footprint of ScanKeyword (was Re: Large writable variables) - Mailing list pgsql-hackers

From Tom Lane
Subject Re: reducing the footprint of ScanKeyword (was Re: Large writable variables)
Date
Msg-id 12359.1547063064@sss.pgh.pa.us
Whole thread Raw
In response to Re: reducing the footprint of ScanKeyword (was Re: Large writable variables)  (Tom Lane <tgl@sss.pgh.pa.us>)
Responses Re: reducing the footprint of ScanKeyword (was Re: Large writablevariables)  (Alvaro Herrera <alvherre@2ndquadrant.com>)
Re: reducing the footprint of ScanKeyword (was Re: Large writablevariables)  (Andres Freund <andres@anarazel.de>)
Re: reducing the footprint of ScanKeyword (was Re: Large writable variables)  (John Naylor <john.naylor@2ndquadrant.com>)
List pgsql-hackers
I wrote:
> Also, I fail to understand why fmgr_builtin_oid_index has 10000 entries
> anyway.  We could easily have fmgrtab.c expose the last actually assigned
> builtin function OID (presently 6121) and make the index array only
> that big, which just about eliminates the space advantage completely.

Concretely, like the attached.

We could make the index table still smaller if we wanted to reassign
a couple dozen high-numbered functions down to lower OIDs, but I dunno
if it's worth the trouble.  It certainly isn't from a performance
standpoint, because those unused entry ranges will never be touched
in normal usage; but it'd make the server executable a couple KB smaller.

            regards, tom lane

diff --git a/src/backend/utils/Gen_fmgrtab.pl b/src/backend/utils/Gen_fmgrtab.pl
index cafe408..f970940 100644
*** a/src/backend/utils/Gen_fmgrtab.pl
--- b/src/backend/utils/Gen_fmgrtab.pl
*************** foreach my $datfile (@input_files)
*** 80,90 ****
      $catalog_data{$catname} = Catalog::ParseData($datfile, $schema, 0);
  }

- # Fetch some values for later.
- my $FirstGenbkiObjectId =
-   Catalog::FindDefinedSymbol('access/transam.h', $include_path,
-     'FirstGenbkiObjectId');
-
  # Collect certain fields from pg_proc.dat.
  my @fmgr = ();

--- 80,85 ----
*************** my %bmap;
*** 225,230 ****
--- 220,226 ----
  $bmap{'t'} = 'true';
  $bmap{'f'} = 'false';
  my @fmgr_builtin_oid_index;
+ my $last_builtin_oid = 0;
  my $fmgr_count = 0;
  foreach my $s (sort { $a->{oid} <=> $b->{oid} } @fmgr)
  {
*************** foreach my $s (sort { $a->{oid} <=> $b->
*** 232,237 ****
--- 228,234 ----
        "  { $s->{oid}, $s->{nargs}, $bmap{$s->{strict}}, $bmap{$s->{retset}}, \"$s->{prosrc}\", $s->{prosrc} }";

      $fmgr_builtin_oid_index[ $s->{oid} ] = $fmgr_count++;
+     $last_builtin_oid = $s->{oid};

      if ($fmgr_count <= $#fmgr)
      {
*************** foreach my $s (sort { $a->{oid} <=> $b->
*** 244,274 ****
  }
  print $tfh "};\n";

! print $tfh qq|
  const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin));
! |;


  # Create fmgr_builtins_oid_index table.
! #
! # Note that the array has to be filled up to FirstGenbkiObjectId,
! # as we can't rely on zero initialization as 0 is a valid mapping.
! print $tfh qq|
! const uint16 fmgr_builtin_oid_index[FirstGenbkiObjectId] = {
! |;

! for (my $i = 0; $i < $FirstGenbkiObjectId; $i++)
  {
      my $oid = $fmgr_builtin_oid_index[$i];

!     # fmgr_builtin_oid_index is sparse, map nonexistant functions to
      # InvalidOidBuiltinMapping
      if (not defined $oid)
      {
          $oid = 'InvalidOidBuiltinMapping';
      }

!     if ($i + 1 == $FirstGenbkiObjectId)
      {
          print $tfh "  $oid\n";
      }
--- 241,270 ----
  }
  print $tfh "};\n";

! printf $tfh qq|
  const int fmgr_nbuiltins = (sizeof(fmgr_builtins) / sizeof(FmgrBuiltin));
!
! const Oid fmgr_last_builtin_oid = %u;
! |, $last_builtin_oid;


  # Create fmgr_builtins_oid_index table.
! printf $tfh qq|
! const uint16 fmgr_builtin_oid_index[%u] = {
! |, $last_builtin_oid + 1;

! for (my $i = 0; $i <= $last_builtin_oid; $i++)
  {
      my $oid = $fmgr_builtin_oid_index[$i];

!     # fmgr_builtin_oid_index is sparse, map nonexistent functions to
      # InvalidOidBuiltinMapping
      if (not defined $oid)
      {
          $oid = 'InvalidOidBuiltinMapping';
      }

!     if ($i == $last_builtin_oid)
      {
          print $tfh "  $oid\n";
      }
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index b41649f..506eeef 100644
*** a/src/backend/utils/fmgr/fmgr.c
--- b/src/backend/utils/fmgr/fmgr.c
*************** fmgr_isbuiltin(Oid id)
*** 75,86 ****
      uint16        index;

      /* fast lookup only possible if original oid still assigned */
!     if (id >= FirstGenbkiObjectId)
          return NULL;

      /*
       * Lookup function data. If there's a miss in that range it's likely a
!      * nonexistant function, returning NULL here will trigger an ERROR later.
       */
      index = fmgr_builtin_oid_index[id];
      if (index == InvalidOidBuiltinMapping)
--- 75,86 ----
      uint16        index;

      /* fast lookup only possible if original oid still assigned */
!     if (id > fmgr_last_builtin_oid)
          return NULL;

      /*
       * Lookup function data. If there's a miss in that range it's likely a
!      * nonexistent function, returning NULL here will trigger an ERROR later.
       */
      index = fmgr_builtin_oid_index[id];
      if (index == InvalidOidBuiltinMapping)
diff --git a/src/include/utils/fmgrtab.h b/src/include/utils/fmgrtab.h
index a778f88..e981f34 100644
*** a/src/include/utils/fmgrtab.h
--- b/src/include/utils/fmgrtab.h
*************** extern const FmgrBuiltin fmgr_builtins[]
*** 36,46 ****

  extern const int fmgr_nbuiltins;    /* number of entries in table */

  /*
!  * Mapping from a builtin function's oid to the index in the fmgr_builtins
!  * array.
   */
  #define InvalidOidBuiltinMapping PG_UINT16_MAX
! extern const uint16 fmgr_builtin_oid_index[FirstGenbkiObjectId];

  #endif                            /* FMGRTAB_H */
--- 36,48 ----

  extern const int fmgr_nbuiltins;    /* number of entries in table */

+ extern const Oid fmgr_last_builtin_oid; /* highest function OID in table */
+
  /*
!  * Mapping from a builtin function's OID to its index in the fmgr_builtins
!  * array.  This is indexed from 0 through fmgr_last_builtin_oid.
   */
  #define InvalidOidBuiltinMapping PG_UINT16_MAX
! extern const uint16 fmgr_builtin_oid_index[];

  #endif                            /* FMGRTAB_H */

pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: reducing the footprint of ScanKeyword (was Re: Large writable variables)
Next
From: Alvaro Herrera
Date:
Subject: Re: reducing the footprint of ScanKeyword (was Re: Large writablevariables)