16
16
#include "postgres_fe.h"
17
17
18
18
#include "catalog/pg_class_d.h"
19
+ #include "lib/binaryheap.h"
19
20
#include "pg_backup_archiver.h"
20
21
#include "pg_backup_utils.h"
21
22
#include "pg_dump.h"
@@ -161,8 +162,6 @@ static bool TopoSort(DumpableObject **objs,
161
162
int numObjs ,
162
163
DumpableObject * * ordering ,
163
164
int * nOrdering );
164
- static void addHeapElement (int val , int * heap , int heapLength );
165
- static int removeHeapElement (int * heap , int heapLength );
166
165
static void findDependencyLoops (DumpableObject * * objs , int nObjs , int totObjs );
167
166
static int findLoop (DumpableObject * obj ,
168
167
DumpId startPoint ,
@@ -174,6 +173,7 @@ static void repairDependencyLoop(DumpableObject **loop,
174
173
int nLoop );
175
174
static void describeDumpableObject (DumpableObject * obj ,
176
175
char * buf , int bufsize );
176
+ static int int_cmp (void * a , void * b , void * arg );
177
177
178
178
179
179
/*
@@ -374,11 +374,10 @@ TopoSort(DumpableObject **objs,
374
374
int * nOrdering ) /* output argument */
375
375
{
376
376
DumpId maxDumpId = getMaxDumpId ();
377
- int * pendingHeap ;
377
+ binaryheap * pendingHeap ;
378
378
int * beforeConstraints ;
379
379
int * idMap ;
380
380
DumpableObject * obj ;
381
- int heapLength ;
382
381
int i ,
383
382
j ,
384
383
k ;
@@ -403,7 +402,7 @@ TopoSort(DumpableObject **objs,
403
402
return true;
404
403
405
404
/* Create workspace for the above-described heap */
406
- pendingHeap = ( int * ) pg_malloc ( numObjs * sizeof ( int ) );
405
+ pendingHeap = binaryheap_allocate ( numObjs , int_cmp , NULL );
407
406
408
407
/*
409
408
* Scan the constraints, and for each item in the input, generate a count
@@ -434,19 +433,16 @@ TopoSort(DumpableObject **objs,
434
433
* Now initialize the heap of items-ready-to-output by filling it with the
435
434
* indexes of items that already have beforeConstraints[id] == 0.
436
435
*
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.
443
439
*/
444
- heapLength = 0 ;
445
440
for (i = numObjs ; -- i >= 0 ;)
446
441
{
447
442
if (beforeConstraints [objs [i ]-> dumpId ] == 0 )
448
- pendingHeap [ heapLength ++ ] = i ;
443
+ binaryheap_add_unordered ( pendingHeap , ( void * ) ( intptr_t ) i ) ;
449
444
}
445
+ binaryheap_build (pendingHeap );
450
446
451
447
/*--------------------
452
448
* Now emit objects, working backwards in the output list. At each step,
@@ -464,10 +460,10 @@ TopoSort(DumpableObject **objs,
464
460
*--------------------
465
461
*/
466
462
i = numObjs ;
467
- while (heapLength > 0 )
463
+ while (! binaryheap_empty ( pendingHeap ) )
468
464
{
469
465
/* Select object to output by removing largest heap member */
470
- j = removeHeapElement ( pendingHeap , heapLength -- );
466
+ j = ( int ) ( intptr_t ) binaryheap_remove_first ( pendingHeap );
471
467
obj = objs [j ];
472
468
/* Output candidate to ordering[] */
473
469
ordering [-- i ] = obj ;
@@ -477,7 +473,7 @@ TopoSort(DumpableObject **objs,
477
473
int id = obj -> dependencies [k ];
478
474
479
475
if ((-- beforeConstraints [id ]) == 0 )
480
- addHeapElement ( idMap [id ], pendingHeap , heapLength ++ );
476
+ binaryheap_add ( pendingHeap , ( void * ) ( intptr_t ) idMap [id ]);
481
477
}
482
478
}
483
479
@@ -497,79 +493,13 @@ TopoSort(DumpableObject **objs,
497
493
}
498
494
499
495
/* Done */
500
- free (pendingHeap );
496
+ binaryheap_free (pendingHeap );
501
497
free (beforeConstraints );
502
498
free (idMap );
503
499
504
500
return (i == 0 );
505
501
}
506
502
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
-
573
503
/*
574
504
* findDependencyLoops - identify loops in TopoSort's failure output,
575
505
* and pass each such loop to repairDependencyLoop() for action
@@ -1559,3 +1489,17 @@ describeDumpableObject(DumpableObject *obj, char *buf, int bufsize)
1559
1489
(int ) obj -> objType ,
1560
1490
obj -> dumpId , obj -> catId .oid );
1561
1491
}
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