Implement missing prio heap functions (MIT-licensed)
authorMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 23 May 2011 16:03:41 +0000 (12:03 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 23 May 2011 16:03:41 +0000 (12:03 -0400)
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
lib/prio_heap/prio_heap.c
lib/prio_heap/prio_heap.h

index e660b0cdc9125ccbc9e99bf83267a9e3540b37b1..0c9bb607510829a0ee62bd3a919d41e4b4b7440e 100644 (file)
 #include <linux/slab.h>
 #include <linux/prio_heap.h>
 
-/*
- * TODO implement heap_init, heap_free, heap_insert.
- */
+int heap_init(struct ptr_heap *heap, size_t size,
+              gfp_t gfpmask, int gt(void *a, void *b))
+{
+       WARN_ON_ONCE(size == 0);
+       heap->ptrs = kmalloc(size * sizeof(void *), gfpmask);
+       if (!heap->ptrs)
+               return -ENOMEM;
+       heap->size = 0;
+       heap->max = size;
+       heap->gt = gt;
+       return 0;
+}
+
+void heap_free(struct ptr_heap *heap)
+{
+       kfree(heap->ptrs);
+}
 
 static void heapify(struct ptr_heap *heap, int pos)
 {
@@ -64,6 +78,34 @@ void *heap_replace_max(struct ptr_heap *heap, void *p)
        return res;
 }
 
+void *heap_insert(struct ptr_heap *heap, void *p)
+{
+       void **ptrs = heap->ptrs;
+       void *tmp = NULL;
+
+       if (heap->size < heap->max) {
+               /* Add the element to the end */
+               heap->ptrs[heap->size++] = p;
+               /* rebalance */
+               heapify(heap, 0);
+               return NULL;
+       }
+
+       /*
+        * Full. We need to replace the largest (if we are
+        * smaller or equal to this element).
+        */
+       if (heap->gt(ptrs[0], p)) {
+               tmp = ptrs[0];
+               ptrs[0] = p;
+               /* rebalance */
+               heapify(heap, 0);
+       } else {
+               tmp = p;
+       }
+       return tmp;
+}
+
 void *heap_remove(struct ptr_heap *heap)
 {
        void **ptrs = heap->ptrs;
index 12b1638f9d46592584fb1f7a62829604fd94b1ca..3a3188534545dc18c86fb6a7785e925572b980b2 100644 (file)
  * all copies or substantial portions of the Software.
  */
 
-/*
- * TODO:
- * implement struct ptr_head, heap_init, heap_free, heap_insert.
- */
+#include <linux/gfp.h>
+
+struct ptr_heap {
+       size_t size, max;
+       void **ptrs;
+       int (*gt)(void *a, void *b);
+};
 
 /**
  * heap_maximum - return the largest element in the heap
@@ -37,6 +40,33 @@ static inline void *heap_maximum(const struct ptr_heap *heap)
        return heap->size ? heap->ptrs[0] : NULL;
 }
 
+/**
+ * heap_init - initialize the heap
+ * @heap: the heap to initialize
+ * @size: maximum number of elements
+ * @gfp: allocation flags
+ * @gt: function to compare the elements
+ *
+ * Returns -ENOMEM if out of memory.
+ */
+extern int heap_init(struct ptr_heap *heap, size_t size,
+                    gfp_t gfpmask, int gt(void *a, void *b));
+
+/**
+ * heap_free - free the heap
+ * @heap: the heap to free
+ */
+extern void heap_free(struct ptr_heap *heap);
+
+/**
+ * heap_insert - insert an element into the heap
+ * @heap: the heap to be operated on
+ *
+ * Insert an element into the heap. If the heap is full, return the
+ * largest element between those previously present in the heap and the
+ * element being added, else return NULL.
+ */
+extern void *heap_insert(struct ptr_heap *heap, void *p);
 
 /**
  * heap_remove - remove the largest element from the heap
This page took 0.027612 seconds and 4 git commands to generate.