1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Code review for FILLFACTOR patch. Change WITH grammar as per earlier

discussion (including making def_arg allow reserved words), add missed
opt_definition for UNIQUE case.  Put the reloptions support code in a less
random place (I chose to make a new file access/common/reloptions.c).
Eliminate header inclusion creep.  Make the index options functions safely
user-callable (seems like client apps might like to be able to test validity
of options before trying to make an index).  Reduce overhead for normal case
with no options by allowing rd_options to be NULL.  Fix some unmaintainably
klugy code, including getting rid of Natts_pg_class_fixed at long last.
Some stylistic cleanup too, and pay attention to keeping comments in sync
with code.

Documentation still needs work, though I did fix the omissions in
catalogs.sgml and indexam.sgml.
This commit is contained in:
Tom Lane
2006-07-03 22:45:41 +00:00
parent feed07350b
commit b7b78d24f7
57 changed files with 1128 additions and 1088 deletions

View File

@@ -8,14 +8,13 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.138 2006/07/02 02:23:18 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.139 2006/07/03 22:45:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/nbtree.h"
#include "miscadmin.h"
@@ -26,7 +25,7 @@ typedef struct
{
/* context data for _bt_checksplitloc */
Size newitemsz; /* size of new item to be inserted */
int fillfactor; /* used when insert at right most */
int fillfactor; /* needed when splitting rightmost page */
bool is_leaf; /* T if splitting a leaf page */
bool is_rightmost; /* T if splitting a rightmost page */
@@ -988,11 +987,11 @@ _bt_split(Relation rel, Buffer buf, OffsetNumber firstright,
* it needs to go into!)
*
* If the page is the rightmost page on its level, we instead try to arrange
* for reserving (100-fillfactor)% of free space on left page. In this way,
* when we are inserting successively increasing keys (consider sequences,
* timestamps, etc) we will end up with a tree whose pages are about fillfactor% full,
* to leave the left split page fillfactor% full. In this way, when we are
* inserting successively increasing keys (consider sequences, timestamps,
* etc) we will end up with a tree whose pages are about fillfactor% full,
* instead of the 50% full result that we'd get without this special case.
* This is the same as initially-loaded tree.
* This is the same as nbtsort.c produces for a newly-created tree.
*
* We are passed the intended insert position of the new tuple, expressed as
* the offsetnumber of the tuple it must go in front of. (This could be
@@ -1026,7 +1025,7 @@ _bt_findsplitloc(Relation rel,
/* Passed-in newitemsz is MAXALIGNED but does not include line pointer */
newitemsz += sizeof(ItemIdData);
state.newitemsz = newitemsz;
state.fillfactor = IndexGetFillFactor(rel);
state.fillfactor = RelationGetFillFactor(rel, BTREE_DEFAULT_FILLFACTOR);
state.is_leaf = P_ISLEAF(opaque);
state.is_rightmost = P_RIGHTMOST(opaque);
state.have_split = false;
@@ -1157,7 +1156,7 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright,
if (state->is_rightmost)
{
/*
* On a rightmost page, try to reserve (100-fillfactor)% of
* If splitting a rightmost page, try to put (100-fillfactor)% of
* free space on left page. See comments for _bt_findsplitloc.
*/
delta = (state->fillfactor * leftfree)

View File

@@ -27,9 +27,10 @@
* insertion would cause a split (and not only of the leaf page; the need
* for a split would cascade right up the tree). The steady-state load
* factor for btrees is usually estimated at 70%. We choose to pack leaf
* pages to 90% and upper pages to 70%. This gives us reasonable density
* (there aren't many upper pages if the keys are reasonable-size) without
* incurring a lot of cascading splits during early insertions.
* pages to the user-controllable fill factor while upper pages are always
* packed to 70%. This gives us reasonable density (there aren't many upper
* pages if the keys are reasonable-size) without incurring a lot of cascading
* splits during early insertions.
*
* Formerly the index pages being built were kept in shared buffers, but
* that is of no value (since other backends have no interest in them yet)
@@ -56,14 +57,13 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.103 2006/07/02 02:23:19 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.104 2006/07/03 22:45:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include "access/genam.h"
#include "access/nbtree.h"
#include "access/xlog.h"
#include "miscadmin.h"
@@ -121,7 +121,6 @@ typedef struct BTWriteState
static Page _bt_blnewpage(uint32 level);
static Size _bt_full_threshold(Relation index, Size pagesize, bool leaf);
static BTPageState *_bt_pagestate(BTWriteState *wstate, uint32 level);
static void _bt_slideleft(Page page);
static void _bt_sortaddtup(Page page, Size itemsize,
@@ -329,22 +328,6 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno)
pfree(page);
}
/*
* The steady-state load factor for btrees is usually estimated at 70%.
* We choose to pack leaf pages to 90% and upper pages to 70% as defaults.
*/
static Size
_bt_full_threshold(Relation index, Size pagesize, bool leaf)
{
int fillfactor = IndexGetFillFactor(index);
if (!leaf)
{
/* XXX: Is this reasonable? */
fillfactor = Max(70, 3 * fillfactor - 200);
}
return pagesize * (100 - fillfactor) / 100;
}
/*
* allocate and initialize a new BTPageState. the returned structure
* is suitable for immediate use by _bt_buildadd.
@@ -365,8 +348,11 @@ _bt_pagestate(BTWriteState *wstate, uint32 level)
state->btps_lastoff = P_HIKEY;
state->btps_level = level;
/* set "full" threshold based on level. See notes at head of file. */
state->btps_full = _bt_full_threshold(wstate->index,
PageGetPageSize(state->btps_page), level == 0);
if (level > 0)
state->btps_full = (BLCKSZ * (100 - BTREE_MIN_FILLFACTOR) / 100);
else
state->btps_full = RelationGetTargetPageFreeSpace(wstate->index,
BTREE_DEFAULT_FILLFACTOR);
/* no parent level, yet */
state->btps_next = NULL;

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.75 2006/07/02 02:23:19 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.76 2006/07/03 22:45:37 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -19,7 +19,7 @@
#include "access/genam.h"
#include "access/nbtree.h"
#include "catalog/catalog.h"
#include "access/reloptions.h"
#include "executor/execdebug.h"
#include "miscadmin.h"
@@ -1081,14 +1081,16 @@ BTreeShmemInit(void)
}
Datum
btoption(PG_FUNCTION_ARGS)
btoptions(PG_FUNCTION_ARGS)
{
#define BTREE_MIN_FILLFACTOR 50
#define BTREE_DEFAULT_FILLFACTOR 90
Datum reloptions = PG_GETARG_DATUM(0);
bool validate = PG_GETARG_BOOL(1);
bytea *result;
ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0);
/* Use index common routine. */
PG_RETURN_BYTEA_P(genam_option(options,
BTREE_MIN_FILLFACTOR, BTREE_DEFAULT_FILLFACTOR));
result = default_reloptions(reloptions, validate,
BTREE_MIN_FILLFACTOR,
BTREE_DEFAULT_FILLFACTOR);
if (result)
PG_RETURN_BYTEA_P(result);
PG_RETURN_NULL();
}