19
19
20
20
static void sift_down (binaryheap * heap , int node_off );
21
21
static void sift_up (binaryheap * heap , int node_off );
22
- static inline void swap_nodes (binaryheap * heap , int a , int b );
23
22
24
23
/*
25
24
* binaryheap_allocate
@@ -173,24 +172,28 @@ binaryheap_first(binaryheap *heap)
173
172
Datum
174
173
binaryheap_remove_first (binaryheap * heap )
175
174
{
175
+ Datum result ;
176
+
176
177
Assert (!binaryheap_empty (heap ) && heap -> bh_has_heap_property );
177
178
179
+ /* extract the root node, which will be the result */
180
+ result = heap -> bh_nodes [0 ];
181
+
182
+ /* easy if heap contains one element */
178
183
if (heap -> bh_size == 1 )
179
184
{
180
185
heap -> bh_size -- ;
181
- return heap -> bh_nodes [ 0 ] ;
186
+ return result ;
182
187
}
183
188
184
189
/*
185
- * Swap the root and last nodes, decrease the size of the heap (i.e.
186
- * remove the former root node) and sift the new root node down to its
187
- * correct position.
190
+ * Remove the last node, placing it in the vacated root entry, and sift
191
+ * the new root node down to its correct position.
188
192
*/
189
- swap_nodes (heap , 0 , heap -> bh_size - 1 );
190
- heap -> bh_size -- ;
193
+ heap -> bh_nodes [0 ] = heap -> bh_nodes [-- heap -> bh_size ];
191
194
sift_down (heap , 0 );
192
195
193
- return heap -> bh_nodes [ heap -> bh_size ] ;
196
+ return result ;
194
197
}
195
198
196
199
/*
@@ -211,49 +214,47 @@ binaryheap_replace_first(binaryheap *heap, Datum d)
211
214
sift_down (heap , 0 );
212
215
}
213
216
214
- /*
215
- * Swap the contents of two nodes.
216
- */
217
- static inline void
218
- swap_nodes (binaryheap * heap , int a , int b )
219
- {
220
- Datum swap ;
221
-
222
- swap = heap -> bh_nodes [a ];
223
- heap -> bh_nodes [a ] = heap -> bh_nodes [b ];
224
- heap -> bh_nodes [b ] = swap ;
225
- }
226
-
227
217
/*
228
218
* Sift a node up to the highest position it can hold according to the
229
219
* comparator.
230
220
*/
231
221
static void
232
222
sift_up (binaryheap * heap , int node_off )
233
223
{
224
+ Datum node_val = heap -> bh_nodes [node_off ];
225
+
226
+ /*
227
+ * Within the loop, the node_off'th array entry is a "hole" that
228
+ * notionally holds node_val, but we don't actually store node_val there
229
+ * till the end, saving some unnecessary data copying steps.
230
+ */
234
231
while (node_off != 0 )
235
232
{
236
233
int cmp ;
237
234
int parent_off ;
235
+ Datum parent_val ;
238
236
239
237
/*
240
238
* If this node is smaller than its parent, the heap condition is
241
239
* satisfied, and we're done.
242
240
*/
243
241
parent_off = parent_offset (node_off );
244
- cmp = heap -> bh_compare (heap -> bh_nodes [node_off ],
245
- heap -> bh_nodes [parent_off ],
242
+ parent_val = heap -> bh_nodes [parent_off ];
243
+ cmp = heap -> bh_compare (node_val ,
244
+ parent_val ,
246
245
heap -> bh_arg );
247
246
if (cmp <= 0 )
248
247
break ;
249
248
250
249
/*
251
- * Otherwise, swap the node and its parent and go on to check the
252
- * node's new parent.
250
+ * Otherwise, swap the parent value with the hole, and go on to check
251
+ * the node's new parent.
253
252
*/
254
- swap_nodes ( heap , node_off , parent_off ) ;
253
+ heap -> bh_nodes [ node_off ] = parent_val ;
255
254
node_off = parent_off ;
256
255
}
256
+ /* Re-fill the hole */
257
+ heap -> bh_nodes [node_off ] = node_val ;
257
258
}
258
259
259
260
/*
@@ -263,6 +264,13 @@ sift_up(binaryheap *heap, int node_off)
263
264
static void
264
265
sift_down (binaryheap * heap , int node_off )
265
266
{
267
+ Datum node_val = heap -> bh_nodes [node_off ];
268
+
269
+ /*
270
+ * Within the loop, the node_off'th array entry is a "hole" that
271
+ * notionally holds node_val, but we don't actually store node_val there
272
+ * till the end, saving some unnecessary data copying steps.
273
+ */
266
274
while (true)
267
275
{
268
276
int left_off = left_offset (node_off );
@@ -271,14 +279,14 @@ sift_down(binaryheap *heap, int node_off)
271
279
272
280
/* Is the left child larger than the parent? */
273
281
if (left_off < heap -> bh_size &&
274
- heap -> bh_compare (heap -> bh_nodes [ node_off ] ,
282
+ heap -> bh_compare (node_val ,
275
283
heap -> bh_nodes [left_off ],
276
284
heap -> bh_arg ) < 0 )
277
285
swap_off = left_off ;
278
286
279
287
/* Is the right child larger than the parent? */
280
288
if (right_off < heap -> bh_size &&
281
- heap -> bh_compare (heap -> bh_nodes [ node_off ] ,
289
+ heap -> bh_compare (node_val ,
282
290
heap -> bh_nodes [right_off ],
283
291
heap -> bh_arg ) < 0 )
284
292
{
@@ -298,10 +306,12 @@ sift_down(binaryheap *heap, int node_off)
298
306
break ;
299
307
300
308
/*
301
- * Otherwise, swap the node with the child that violates the heap
309
+ * Otherwise, swap the hole with the child that violates the heap
302
310
* property; then go on to check its children.
303
311
*/
304
- swap_nodes ( heap , swap_off , node_off ) ;
312
+ heap -> bh_nodes [ node_off ] = heap -> bh_nodes [ swap_off ] ;
305
313
node_off = swap_off ;
306
314
}
315
+ /* Re-fill the hole */
316
+ heap -> bh_nodes [node_off ] = node_val ;
307
317
}
0 commit comments