diff options
Diffstat (limited to 'src/backend/access/nbtree')
| -rw-r--r-- | src/backend/access/nbtree/nbtinsert.c | 21 | ||||
| -rw-r--r-- | src/backend/access/nbtree/nbtsort.c | 26 | ||||
| -rw-r--r-- | src/backend/access/nbtree/nbtutils.c | 15 |
3 files changed, 46 insertions, 16 deletions
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c index 89f8810bde..3b78843101 100644 --- a/src/backend/access/nbtree/nbtinsert.c +++ b/src/backend/access/nbtree/nbtinsert.c @@ -8,13 +8,14 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.137 2006/05/08 00:00:09 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.138 2006/07/02 02:23:18 momjian Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/genam.h" #include "access/heapam.h" #include "access/nbtree.h" #include "miscadmin.h" @@ -25,6 +26,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 */ bool is_leaf; /* T if splitting a leaf page */ bool is_rightmost; /* T if splitting a rightmost page */ @@ -986,14 +988,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 twice as much free space on the right as on the left. In this way, + * 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 67% full, + * 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. - * (We could bias it even further to make the initially-loaded tree more full. - * But since the steady-state load for a btree is about 70%, we'd likely just - * be making more page-splitting work for ourselves later on, when we start - * seeing updates to existing tuples.) + * This is the same as initially-loaded 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 @@ -1027,6 +1026,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.is_leaf = P_ISLEAF(opaque); state.is_rightmost = P_RIGHTMOST(opaque); state.have_split = false; @@ -1157,10 +1157,11 @@ _bt_checksplitloc(FindSplitData *state, OffsetNumber firstright, if (state->is_rightmost) { /* - * On a rightmost page, try to equalize right free space with - * twice the left free space. See comments for _bt_findsplitloc. + * On a rightmost page, try to reserve (100-fillfactor)% of + * free space on left page. See comments for _bt_findsplitloc. */ - delta = (2 * leftfree) - rightfree; + delta = (state->fillfactor * leftfree) + - ((100 - state->fillfactor) * rightfree); } else { diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c index e7293b47b0..05785d98eb 100644 --- a/src/backend/access/nbtree/nbtsort.c +++ b/src/backend/access/nbtree/nbtsort.c @@ -56,13 +56,14 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.102 2006/06/27 16:53:02 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtsort.c,v 1.103 2006/07/02 02:23:19 momjian Exp $ * *------------------------------------------------------------------------- */ #include "postgres.h" +#include "access/genam.h" #include "access/nbtree.h" #include "access/xlog.h" #include "miscadmin.h" @@ -120,6 +121,7 @@ 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, @@ -328,6 +330,22 @@ _bt_blwritepage(BTWriteState *wstate, Page page, BlockNumber blkno) } /* + * 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. */ @@ -347,10 +365,8 @@ _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. */ - if (level > 0) - state->btps_full = (PageGetPageSize(state->btps_page) * 3) / 10; - else - state->btps_full = PageGetPageSize(state->btps_page) / 10; + state->btps_full = _bt_full_threshold(wstate->index, + PageGetPageSize(state->btps_page), level == 0); /* no parent level, yet */ state->btps_next = NULL; diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c index 5db8f55288..93a9b0df65 100644 --- a/src/backend/access/nbtree/nbtutils.c +++ b/src/backend/access/nbtree/nbtutils.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.74 2006/05/08 00:00:10 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/access/nbtree/nbtutils.c,v 1.75 2006/07/02 02:23:19 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -1079,3 +1079,16 @@ BTreeShmemInit(void) else Assert(found); } + +Datum +btoption(PG_FUNCTION_ARGS) +{ +#define BTREE_MIN_FILLFACTOR 50 +#define BTREE_DEFAULT_FILLFACTOR 90 + + ArrayType *options = (ArrayType *) PG_GETARG_POINTER(0); + + /* Use index common routine. */ + PG_RETURN_BYTEA_P(genam_option(options, + BTREE_MIN_FILLFACTOR, BTREE_DEFAULT_FILLFACTOR)); +} |
