aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/lib/pairingheap.c59
-rw-r--r--src/include/lib/pairingheap.h11
2 files changed, 70 insertions, 0 deletions
diff --git a/src/backend/lib/pairingheap.c b/src/backend/lib/pairingheap.c
index 213c9d3466c..17278fde6ea 100644
--- a/src/backend/lib/pairingheap.c
+++ b/src/backend/lib/pairingheap.c
@@ -70,6 +70,10 @@ pairingheap_free(pairingheap *heap)
*
* The subheap with smaller value is put as a child of the other one (assuming
* a max-heap).
+ *
+ * The next_sibling and prev_or_parent pointers of the input nodes are
+ * ignored. On return, the returned node's next_sibling and prev_or_parent
+ * pointers are garbage.
*/
static pairingheap_node *
merge(pairingheap *heap, pairingheap_node *a, pairingheap_node *b)
@@ -111,6 +115,8 @@ pairingheap_add(pairingheap *heap, pairingheap_node *node)
/* Link the new node as a new tree */
heap->ph_root = merge(heap, heap->ph_root, node);
+ heap->ph_root->prev_or_parent = NULL;
+ heap->ph_root->next_sibling = NULL;
}
/*
@@ -148,6 +154,11 @@ pairingheap_remove_first(pairingheap *heap)
children = result->first_child;
heap->ph_root = merge_children(heap, children);
+ if (heap->ph_root)
+ {
+ heap->ph_root->prev_or_parent = NULL;
+ heap->ph_root->next_sibling = NULL;
+ }
return result;
}
@@ -272,3 +283,51 @@ merge_children(pairingheap *heap, pairingheap_node *children)
return newroot;
}
+
+/*
+ * A debug function to dump the contents of the heap as a string.
+ *
+ * The 'dumpfunc' callback appends a string representation of a single node
+ * to the StringInfo. 'opaque' can be used to pass more information to the
+ * callback.
+ */
+#ifdef PAIRINGHEAP_DEBUG
+static void
+pairingheap_dump_recurse(StringInfo buf,
+ pairingheap_node *node,
+ void (*dumpfunc) (pairingheap_node *node, StringInfo buf, void *opaque),
+ void *opaque,
+ int depth,
+ pairingheap_node *prev_or_parent)
+{
+ while (node)
+ {
+ Assert(node->prev_or_parent == prev_or_parent);
+
+ appendStringInfoSpaces(buf, depth * 4);
+ dumpfunc(node, buf, opaque);
+ appendStringInfoString(buf, "\n");
+ if (node->first_child)
+ pairingheap_dump_recurse(buf, node->first_child, dumpfunc, opaque, depth + 1, node);
+ prev_or_parent = node;
+ node = node->next_sibling;
+ }
+}
+
+char *
+pairingheap_dump(pairingheap *heap,
+ void (*dumpfunc) (pairingheap_node *node, StringInfo buf, void *opaque),
+ void *opaque)
+{
+ StringInfoData buf;
+
+ if (!heap->ph_root)
+ return pstrdup("(empty)");
+
+ initStringInfo(&buf);
+
+ pairingheap_dump_recurse(&buf, heap->ph_root, dumpfunc, opaque, 0, NULL);
+
+ return buf.data;
+}
+#endif
diff --git a/src/include/lib/pairingheap.h b/src/include/lib/pairingheap.h
index e3e320fc434..eb1856a7c10 100644
--- a/src/include/lib/pairingheap.h
+++ b/src/include/lib/pairingheap.h
@@ -11,6 +11,11 @@
#ifndef PAIRINGHEAP_H
#define PAIRINGHEAP_H
+#include "lib/stringinfo.h"
+
+/* Enable if you need the pairingheap_dump() debug function */
+/* #define PAIRINGHEAP_DEBUG */
+
/*
* This represents an element stored in the heap. Embed this in a larger
* struct containing the actual data you're storing.
@@ -78,6 +83,12 @@ extern pairingheap_node *pairingheap_first(pairingheap *heap);
extern pairingheap_node *pairingheap_remove_first(pairingheap *heap);
extern void pairingheap_remove(pairingheap *heap, pairingheap_node *node);
+#ifdef PAIRINGHEAP_DEBUG
+extern char *pairingheap_dump(pairingheap *heap,
+ void (*dumpfunc) (pairingheap_node *node, StringInfo buf, void *opaque),
+ void *opaque);
+#endif
+
/* Resets the heap to be empty. */
#define pairingheap_reset(h) ((h)->ph_root = NULL)