1616#include "postgres_fe.h"
1717
1818#include "catalog/pg_class_d.h"
19+ #include "lib/binaryheap.h"
1920#include "pg_backup_archiver.h"
2021#include "pg_backup_utils.h"
2122#include "pg_dump.h"
@@ -161,8 +162,6 @@ static bool TopoSort(DumpableObject **objs,
161162 int numObjs ,
162163 DumpableObject * * ordering ,
163164 int * nOrdering );
164- static void addHeapElement (int val , int * heap , int heapLength );
165- static int removeHeapElement (int * heap , int heapLength );
166165static void findDependencyLoops (DumpableObject * * objs , int nObjs , int totObjs );
167166static int findLoop (DumpableObject * obj ,
168167 DumpId startPoint ,
@@ -174,6 +173,7 @@ static void repairDependencyLoop(DumpableObject **loop,
174173 int nLoop );
175174static void describeDumpableObject (DumpableObject * obj ,
176175 char * buf , int bufsize );
176+ static int int_cmp (void * a , void * b , void * arg );
177177
178178
179179/*
@@ -374,11 +374,10 @@ TopoSort(DumpableObject **objs,
374374 int * nOrdering ) /* output argument */
375375{
376376 DumpId maxDumpId = getMaxDumpId ();
377- int * pendingHeap ;
377+ binaryheap * pendingHeap ;
378378 int * beforeConstraints ;
379379 int * idMap ;
380380 DumpableObject * obj ;
381- int heapLength ;
382381 int i ,
383382 j ,
384383 k ;
@@ -403,7 +402,7 @@ TopoSort(DumpableObject **objs,
403402 return true;
404403
405404 /* Create workspace for the above-described heap */
406- pendingHeap = ( int * ) pg_malloc ( numObjs * sizeof ( int ) );
405+ pendingHeap = binaryheap_allocate ( numObjs , int_cmp , NULL );
407406
408407 /*
409408 * Scan the constraints, and for each item in the input, generate a count
@@ -434,19 +433,16 @@ TopoSort(DumpableObject **objs,
434433 * Now initialize the heap of items-ready-to-output by filling it with the
435434 * indexes of items that already have beforeConstraints[id] == 0.
436435 *
437- * The essential property of a heap is heap[(j-1)/2] >= heap[j] for each j
438- * in the range 1..heapLength-1 (note we are using 0-based subscripts
439- * here, while the discussion in Knuth assumes 1-based subscripts). So, if
440- * we simply enter the indexes into pendingHeap[] in decreasing order, we
441- * a-fortiori have the heap invariant satisfied at completion of this
442- * loop, and don't need to do any sift-up comparisons.
436+ * We enter the indexes into pendingHeap in decreasing order so that the
437+ * heap invariant is satisfied at the completion of this loop. This
438+ * reduces the amount of work that binaryheap_build() must do.
443439 */
444- heapLength = 0 ;
445440 for (i = numObjs ; -- i >= 0 ;)
446441 {
447442 if (beforeConstraints [objs [i ]-> dumpId ] == 0 )
448- pendingHeap [ heapLength ++ ] = i ;
443+ binaryheap_add_unordered ( pendingHeap , ( void * ) ( intptr_t ) i ) ;
449444 }
445+ binaryheap_build (pendingHeap );
450446
451447 /*--------------------
452448 * Now emit objects, working backwards in the output list. At each step,
@@ -464,10 +460,10 @@ TopoSort(DumpableObject **objs,
464460 *--------------------
465461 */
466462 i = numObjs ;
467- while (heapLength > 0 )
463+ while (! binaryheap_empty ( pendingHeap ) )
468464 {
469465 /* Select object to output by removing largest heap member */
470- j = removeHeapElement ( pendingHeap , heapLength -- );
466+ j = ( int ) ( intptr_t ) binaryheap_remove_first ( pendingHeap );
471467 obj = objs [j ];
472468 /* Output candidate to ordering[] */
473469 ordering [-- i ] = obj ;
@@ -477,7 +473,7 @@ TopoSort(DumpableObject **objs,
477473 int id = obj -> dependencies [k ];
478474
479475 if ((-- beforeConstraints [id ]) == 0 )
480- addHeapElement ( idMap [id ], pendingHeap , heapLength ++ );
476+ binaryheap_add ( pendingHeap , ( void * ) ( intptr_t ) idMap [id ]);
481477 }
482478 }
483479
@@ -497,79 +493,13 @@ TopoSort(DumpableObject **objs,
497493 }
498494
499495 /* Done */
500- free (pendingHeap );
496+ binaryheap_free (pendingHeap );
501497 free (beforeConstraints );
502498 free (idMap );
503499
504500 return (i == 0 );
505501}
506502
507- /*
508- * Add an item to a heap (priority queue)
509- *
510- * heapLength is the current heap size; caller is responsible for increasing
511- * its value after the call. There must be sufficient storage at *heap.
512- */
513- static void
514- addHeapElement (int val , int * heap , int heapLength )
515- {
516- int j ;
517-
518- /*
519- * Sift-up the new entry, per Knuth 5.2.3 exercise 16. Note that Knuth is
520- * using 1-based array indexes, not 0-based.
521- */
522- j = heapLength ;
523- while (j > 0 )
524- {
525- int i = (j - 1 ) >> 1 ;
526-
527- if (val <= heap [i ])
528- break ;
529- heap [j ] = heap [i ];
530- j = i ;
531- }
532- heap [j ] = val ;
533- }
534-
535- /*
536- * Remove the largest item present in a heap (priority queue)
537- *
538- * heapLength is the current heap size; caller is responsible for decreasing
539- * its value after the call.
540- *
541- * We remove and return heap[0], which is always the largest element of
542- * the heap, and then "sift up" to maintain the heap invariant.
543- */
544- static int
545- removeHeapElement (int * heap , int heapLength )
546- {
547- int result = heap [0 ];
548- int val ;
549- int i ;
550-
551- if (-- heapLength <= 0 )
552- return result ;
553- val = heap [heapLength ]; /* value that must be reinserted */
554- i = 0 ; /* i is where the "hole" is */
555- for (;;)
556- {
557- int j = 2 * i + 1 ;
558-
559- if (j >= heapLength )
560- break ;
561- if (j + 1 < heapLength &&
562- heap [j ] < heap [j + 1 ])
563- j ++ ;
564- if (val >= heap [j ])
565- break ;
566- heap [i ] = heap [j ];
567- i = j ;
568- }
569- heap [i ] = val ;
570- return result ;
571- }
572-
573503/*
574504 * findDependencyLoops - identify loops in TopoSort's failure output,
575505 * and pass each such loop to repairDependencyLoop() for action
@@ -1559,3 +1489,17 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
15591489 (int ) obj -> objType ,
15601490 obj -> dumpId , obj -> catId .oid );
15611491}
1492+
1493+ /* binaryheap comparator that compares "a" and "b" as integers */
1494+ static int
1495+ int_cmp (void * a , void * b , void * arg )
1496+ {
1497+ int ai = (int ) (intptr_t ) a ;
1498+ int bi = (int ) (intptr_t ) b ;
1499+
1500+ if (ai < bi )
1501+ return -1 ;
1502+ if (ai > bi )
1503+ return 1 ;
1504+ return 0 ;
1505+ }
0 commit comments