Commit 5209c084 authored by Teodor Sigaev's avatar Teodor Sigaev

Generic implementation of red-black binary tree. It's planned to use in

several places, but for now only GIN uses it during index creation.
Using self-balanced tree greatly speeds up index creation in corner cases
with preordered data.
parent 161d9d51
This diff is collapsed.
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/ginfast.c,v 1.6 2010/01/02 16:57:33 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/gin/ginfast.c,v 1.7 2010/02/11 14:29:50 teodor Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -765,8 +765,7 @@ ginInsertCleanup(Relation index, GinState *ginstate, ...@@ -765,8 +765,7 @@ ginInsertCleanup(Relation index, GinState *ginstate,
*/ */
if (GinPageGetOpaque(page)->rightlink == InvalidBlockNumber || if (GinPageGetOpaque(page)->rightlink == InvalidBlockNumber ||
(GinPageHasFullRow(page) && (GinPageHasFullRow(page) &&
(accum.allocatedMemory >= maintenance_work_mem * 1024L || (accum.allocatedMemory >= maintenance_work_mem * 1024L)))
accum.maxdepth > GIN_MAX_TREE_DEPTH)))
{ {
ItemPointerData *list; ItemPointerData *list;
uint32 nlist; uint32 nlist;
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.25 2010/01/02 16:57:33 momjian Exp $ * $PostgreSQL: pgsql/src/backend/access/gin/gininsert.c,v 1.26 2010/02/11 14:29:50 teodor Exp $
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -247,9 +247,7 @@ ginBuildCallback(Relation index, HeapTuple htup, Datum *values, ...@@ -247,9 +247,7 @@ ginBuildCallback(Relation index, HeapTuple htup, Datum *values,
&htup->t_self); &htup->t_self);
/* If we've maxed out our available memory, dump everything to the index */ /* If we've maxed out our available memory, dump everything to the index */
/* Also dump if the tree seems to be getting too unbalanced */ if (buildstate->accum.allocatedMemory >= maintenance_work_mem * 1024L)
if (buildstate->accum.allocatedMemory >= maintenance_work_mem * 1024L ||
buildstate->accum.maxdepth > GIN_MAX_TREE_DEPTH)
{ {
ItemPointerData *list; ItemPointerData *list;
Datum entry; Datum entry;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
# Makefile for utils/misc # Makefile for utils/misc
# #
# IDENTIFICATION # IDENTIFICATION
# $PostgreSQL: pgsql/src/backend/utils/misc/Makefile,v 1.29 2009/08/28 20:26:19 petere Exp $ # $PostgreSQL: pgsql/src/backend/utils/misc/Makefile,v 1.30 2010/02/11 14:29:50 teodor Exp $
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
...@@ -14,7 +14,8 @@ include $(top_builddir)/src/Makefile.global ...@@ -14,7 +14,8 @@ include $(top_builddir)/src/Makefile.global
override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS) override CPPFLAGS := -I. -I$(srcdir) $(CPPFLAGS)
OBJS = guc.o help_config.o pg_rusage.o ps_status.o superuser.o tzparser.o OBJS = guc.o help_config.o pg_rusage.o ps_status.o superuser.o tzparser.o \
rbtree.o
# This location might depend on the installation directories. Therefore # This location might depend on the installation directories. Therefore
# we can't subsitute it into pg_config.h. # we can't subsitute it into pg_config.h.
......
This diff is collapsed.
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* Copyright (c) 2006-2010, PostgreSQL Global Development Group * Copyright (c) 2006-2010, PostgreSQL Global Development Group
* *
* $PostgreSQL: pgsql/src/include/access/gin.h,v 1.36 2010/01/02 16:58:00 momjian Exp $ * $PostgreSQL: pgsql/src/include/access/gin.h,v 1.37 2010/02/11 14:29:50 teodor Exp $
*-------------------------------------------------------------------------- *--------------------------------------------------------------------------
*/ */
#ifndef GIN_H #ifndef GIN_H
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include "access/genam.h" #include "access/genam.h"
#include "access/itup.h" #include "access/itup.h"
#include "access/xlog.h" #include "access/xlog.h"
#include "utils/rbtree.h"
#include "fmgr.h" #include "fmgr.h"
...@@ -26,14 +27,6 @@ ...@@ -26,14 +27,6 @@
#define GIN_COMPARE_PARTIAL_PROC 5 #define GIN_COMPARE_PARTIAL_PROC 5
#define GINNProcs 5 #define GINNProcs 5
/*
* Max depth allowed in search tree during bulk inserts. This is to keep from
* degenerating to O(N^2) behavior when the tree is unbalanced due to sorted
* or nearly-sorted input. (Perhaps it would be better to use a balanced-tree
* algorithm, but in common cases that would only add useless overhead.)
*/
#define GIN_MAX_TREE_DEPTH 100
/* /*
* Page opaque data in a inverted index page. * Page opaque data in a inverted index page.
* *
...@@ -570,27 +563,23 @@ extern Datum ginarrayconsistent(PG_FUNCTION_ARGS); ...@@ -570,27 +563,23 @@ extern Datum ginarrayconsistent(PG_FUNCTION_ARGS);
/* ginbulk.c */ /* ginbulk.c */
typedef struct EntryAccumulator typedef struct EntryAccumulator
{ {
OffsetNumber attnum;
Datum value; Datum value;
uint32 length; uint32 length;
uint32 number; uint32 number;
ItemPointerData *list; OffsetNumber attnum;
bool shouldSort; bool shouldSort;
struct EntryAccumulator *left; ItemPointerData *list;
struct EntryAccumulator *right;
} EntryAccumulator; } EntryAccumulator;
typedef struct typedef struct
{ {
GinState *ginstate; GinState *ginstate;
EntryAccumulator *entries;
uint32 maxdepth;
EntryAccumulator **stack;
uint32 stackpos;
long allocatedMemory; long allocatedMemory;
uint32 length; uint32 length;
EntryAccumulator *entryallocator; EntryAccumulator *entryallocator;
ItemPointerData *tmpList;
RBTree *tree;
RBTreeIterator *iterator;
} BuildAccumulator; } BuildAccumulator;
extern void ginInitBA(BuildAccumulator *accum); extern void ginInitBA(BuildAccumulator *accum);
......
/*-------------------------------------------------------------------------
*
* rbtree.h
* interface for PostgreSQL generic Red-Black binary tree package
*
* Copyright (c) 1996-2009, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/include/utils/rbtree.h,v 1.1 2010/02/11 14:29:50 teodor Exp $
*
*-------------------------------------------------------------------------
*/
#ifndef RBTREE_H
#define RBTREE_H
typedef struct RBTree RBTree;
typedef struct RBTreeIterator RBTreeIterator;
typedef int (*rb_comparator) (const void *a, const void *b, void *arg);
typedef void* (*rb_appendator) (void *current, void *new, void *arg);
typedef void (*rb_freefunc) (void *a);
extern RBTree *rb_create(rb_comparator comparator,
rb_appendator appendator,
rb_freefunc freefunc,
void *arg);
extern void *rb_find(RBTree *rb, void *data);
extern void *rb_insert(RBTree *rb, void *data);
extern void rb_delete(RBTree *rb, void *data);
extern void *rb_leftmost(RBTree *rb);
typedef enum RBOrderControl
{
LeftRightWalk,
RightLeftWalk,
DirectWalk,
InvertedWalk
} RBOrderControl;
extern RBTreeIterator* rb_begin_iterate(RBTree *rb, RBOrderControl ctrl);
extern void *rb_iterate(RBTreeIterator *iterator);
extern void rb_free_iterator(RBTreeIterator *iterator);
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment