Remove open-coded binary heap in pg_dump_sort.c.
Thanks to commit 5af0263afd, binaryheap is available to frontend code. This commit replaces the open-coded heap implementation in pg_dump_sort.c with a binaryheap, saving a few lines of code. Reviewed-by: Tom Lane Discussion: https://postgr.es/m/3612876.1689443232%40sss.pgh.pa.us
This commit is contained in:
parent
c868cbfef7
commit
559bc17321
@ -16,6 +16,7 @@
|
|||||||
#include "postgres_fe.h"
|
#include "postgres_fe.h"
|
||||||
|
|
||||||
#include "catalog/pg_class_d.h"
|
#include "catalog/pg_class_d.h"
|
||||||
|
#include "lib/binaryheap.h"
|
||||||
#include "pg_backup_archiver.h"
|
#include "pg_backup_archiver.h"
|
||||||
#include "pg_backup_utils.h"
|
#include "pg_backup_utils.h"
|
||||||
#include "pg_dump.h"
|
#include "pg_dump.h"
|
||||||
@ -161,8 +162,6 @@ static bool TopoSort(DumpableObject **objs,
|
|||||||
int numObjs,
|
int numObjs,
|
||||||
DumpableObject **ordering,
|
DumpableObject **ordering,
|
||||||
int *nOrdering);
|
int *nOrdering);
|
||||||
static void addHeapElement(int val, int *heap, int heapLength);
|
|
||||||
static int removeHeapElement(int *heap, int heapLength);
|
|
||||||
static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs);
|
static void findDependencyLoops(DumpableObject **objs, int nObjs, int totObjs);
|
||||||
static int findLoop(DumpableObject *obj,
|
static int findLoop(DumpableObject *obj,
|
||||||
DumpId startPoint,
|
DumpId startPoint,
|
||||||
@ -174,6 +173,7 @@ static void repairDependencyLoop(DumpableObject **loop,
|
|||||||
int nLoop);
|
int nLoop);
|
||||||
static void describeDumpableObject(DumpableObject *obj,
|
static void describeDumpableObject(DumpableObject *obj,
|
||||||
char *buf, int bufsize);
|
char *buf, int bufsize);
|
||||||
|
static int int_cmp(void *a, void *b, void *arg);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -374,11 +374,10 @@ TopoSort(DumpableObject **objs,
|
|||||||
int *nOrdering) /* output argument */
|
int *nOrdering) /* output argument */
|
||||||
{
|
{
|
||||||
DumpId maxDumpId = getMaxDumpId();
|
DumpId maxDumpId = getMaxDumpId();
|
||||||
int *pendingHeap;
|
binaryheap *pendingHeap;
|
||||||
int *beforeConstraints;
|
int *beforeConstraints;
|
||||||
int *idMap;
|
int *idMap;
|
||||||
DumpableObject *obj;
|
DumpableObject *obj;
|
||||||
int heapLength;
|
|
||||||
int i,
|
int i,
|
||||||
j,
|
j,
|
||||||
k;
|
k;
|
||||||
@ -403,7 +402,7 @@ TopoSort(DumpableObject **objs,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
/* Create workspace for the above-described heap */
|
/* Create workspace for the above-described heap */
|
||||||
pendingHeap = (int *) pg_malloc(numObjs * sizeof(int));
|
pendingHeap = binaryheap_allocate(numObjs, int_cmp, NULL);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Scan the constraints, and for each item in the input, generate a count
|
* Scan the constraints, and for each item in the input, generate a count
|
||||||
@ -434,19 +433,16 @@ TopoSort(DumpableObject **objs,
|
|||||||
* Now initialize the heap of items-ready-to-output by filling it with the
|
* Now initialize the heap of items-ready-to-output by filling it with the
|
||||||
* indexes of items that already have beforeConstraints[id] == 0.
|
* indexes of items that already have beforeConstraints[id] == 0.
|
||||||
*
|
*
|
||||||
* The essential property of a heap is heap[(j-1)/2] >= heap[j] for each j
|
* We enter the indexes into pendingHeap in decreasing order so that the
|
||||||
* in the range 1..heapLength-1 (note we are using 0-based subscripts
|
* heap invariant is satisfied at the completion of this loop. This
|
||||||
* here, while the discussion in Knuth assumes 1-based subscripts). So, if
|
* reduces the amount of work that binaryheap_build() must do.
|
||||||
* we simply enter the indexes into pendingHeap[] in decreasing order, we
|
|
||||||
* a-fortiori have the heap invariant satisfied at completion of this
|
|
||||||
* loop, and don't need to do any sift-up comparisons.
|
|
||||||
*/
|
*/
|
||||||
heapLength = 0;
|
|
||||||
for (i = numObjs; --i >= 0;)
|
for (i = numObjs; --i >= 0;)
|
||||||
{
|
{
|
||||||
if (beforeConstraints[objs[i]->dumpId] == 0)
|
if (beforeConstraints[objs[i]->dumpId] == 0)
|
||||||
pendingHeap[heapLength++] = i;
|
binaryheap_add_unordered(pendingHeap, (void *) (intptr_t) i);
|
||||||
}
|
}
|
||||||
|
binaryheap_build(pendingHeap);
|
||||||
|
|
||||||
/*--------------------
|
/*--------------------
|
||||||
* Now emit objects, working backwards in the output list. At each step,
|
* Now emit objects, working backwards in the output list. At each step,
|
||||||
@ -464,10 +460,10 @@ TopoSort(DumpableObject **objs,
|
|||||||
*--------------------
|
*--------------------
|
||||||
*/
|
*/
|
||||||
i = numObjs;
|
i = numObjs;
|
||||||
while (heapLength > 0)
|
while (!binaryheap_empty(pendingHeap))
|
||||||
{
|
{
|
||||||
/* Select object to output by removing largest heap member */
|
/* Select object to output by removing largest heap member */
|
||||||
j = removeHeapElement(pendingHeap, heapLength--);
|
j = (int) (intptr_t) binaryheap_remove_first(pendingHeap);
|
||||||
obj = objs[j];
|
obj = objs[j];
|
||||||
/* Output candidate to ordering[] */
|
/* Output candidate to ordering[] */
|
||||||
ordering[--i] = obj;
|
ordering[--i] = obj;
|
||||||
@ -477,7 +473,7 @@ TopoSort(DumpableObject **objs,
|
|||||||
int id = obj->dependencies[k];
|
int id = obj->dependencies[k];
|
||||||
|
|
||||||
if ((--beforeConstraints[id]) == 0)
|
if ((--beforeConstraints[id]) == 0)
|
||||||
addHeapElement(idMap[id], pendingHeap, heapLength++);
|
binaryheap_add(pendingHeap, (void *) (intptr_t) idMap[id]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -497,79 +493,13 @@ TopoSort(DumpableObject **objs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Done */
|
/* Done */
|
||||||
free(pendingHeap);
|
binaryheap_free(pendingHeap);
|
||||||
free(beforeConstraints);
|
free(beforeConstraints);
|
||||||
free(idMap);
|
free(idMap);
|
||||||
|
|
||||||
return (i == 0);
|
return (i == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Add an item to a heap (priority queue)
|
|
||||||
*
|
|
||||||
* heapLength is the current heap size; caller is responsible for increasing
|
|
||||||
* its value after the call. There must be sufficient storage at *heap.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
addHeapElement(int val, int *heap, int heapLength)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Sift-up the new entry, per Knuth 5.2.3 exercise 16. Note that Knuth is
|
|
||||||
* using 1-based array indexes, not 0-based.
|
|
||||||
*/
|
|
||||||
j = heapLength;
|
|
||||||
while (j > 0)
|
|
||||||
{
|
|
||||||
int i = (j - 1) >> 1;
|
|
||||||
|
|
||||||
if (val <= heap[i])
|
|
||||||
break;
|
|
||||||
heap[j] = heap[i];
|
|
||||||
j = i;
|
|
||||||
}
|
|
||||||
heap[j] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remove the largest item present in a heap (priority queue)
|
|
||||||
*
|
|
||||||
* heapLength is the current heap size; caller is responsible for decreasing
|
|
||||||
* its value after the call.
|
|
||||||
*
|
|
||||||
* We remove and return heap[0], which is always the largest element of
|
|
||||||
* the heap, and then "sift up" to maintain the heap invariant.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
removeHeapElement(int *heap, int heapLength)
|
|
||||||
{
|
|
||||||
int result = heap[0];
|
|
||||||
int val;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (--heapLength <= 0)
|
|
||||||
return result;
|
|
||||||
val = heap[heapLength]; /* value that must be reinserted */
|
|
||||||
i = 0; /* i is where the "hole" is */
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
int j = 2 * i + 1;
|
|
||||||
|
|
||||||
if (j >= heapLength)
|
|
||||||
break;
|
|
||||||
if (j + 1 < heapLength &&
|
|
||||||
heap[j] < heap[j + 1])
|
|
||||||
j++;
|
|
||||||
if (val >= heap[j])
|
|
||||||
break;
|
|
||||||
heap[i] = heap[j];
|
|
||||||
i = j;
|
|
||||||
}
|
|
||||||
heap[i] = val;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* findDependencyLoops - identify loops in TopoSort's failure output,
|
* findDependencyLoops - identify loops in TopoSort's failure output,
|
||||||
* and pass each such loop to repairDependencyLoop() for action
|
* and pass each such loop to repairDependencyLoop() for action
|
||||||
@ -1559,3 +1489,17 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
|
|||||||
(int) obj->objType,
|
(int) obj->objType,
|
||||||
obj->dumpId, obj->catId.oid);
|
obj->dumpId, obj->catId.oid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* binaryheap comparator that compares "a" and "b" as integers */
|
||||||
|
static int
|
||||||
|
int_cmp(void *a, void *b, void *arg)
|
||||||
|
{
|
||||||
|
int ai = (int) (intptr_t) a;
|
||||||
|
int bi = (int) (intptr_t) b;
|
||||||
|
|
||||||
|
if (ai < bi)
|
||||||
|
return -1;
|
||||||
|
if (ai > bi)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user