Remove GPL heapify implementation
[lttng-modules.git] / lib / prio_heap / prio_heap.c
CommitLineData
f3bc08c5 1/*
162769ef
MD
2 * prio_heap.c
3 *
4 * Static-sized priority heap containing pointers. Based on CLRS,
5 * chapter 6.
6 *
7 * Copyright 2011 - Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this software and associated documentation files (the "Software"), to deal
11 * in the Software without restriction, including without limitation the rights
12 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 * copies of the Software, and to permit persons to whom the Software is
14 * furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
f3bc08c5
MD
18 */
19
20#include <linux/slab.h>
21#include <linux/prio_heap.h>
22
c9891db2
MD
23int heap_init(struct ptr_heap *heap, size_t size,
24 gfp_t gfpmask, int gt(void *a, void *b))
25{
26 WARN_ON_ONCE(size == 0);
27 heap->ptrs = kmalloc(size * sizeof(void *), gfpmask);
28 if (!heap->ptrs)
29 return -ENOMEM;
30 heap->size = 0;
31 heap->max = size;
32 heap->gt = gt;
33 return 0;
34}
35
36void heap_free(struct ptr_heap *heap)
37{
38 kfree(heap->ptrs);
39}
f3bc08c5
MD
40
41static void heapify(struct ptr_heap *heap, int pos)
42{
94a7d04e 43 /* TODO */
f3bc08c5
MD
44}
45
46void *heap_replace_max(struct ptr_heap *heap, void *p)
47{
48 void *res;
49 void **ptrs = heap->ptrs;
50
51 if (!heap->size) {
52 ptrs[0] = p;
53 heap->size = 1;
54 return NULL;
55 }
56
57 /* Replace the current max and heapify */
58 res = ptrs[0];
59 ptrs[0] = p;
60 heapify(heap, 0);
61 return res;
62}
63
c9891db2
MD
64void *heap_insert(struct ptr_heap *heap, void *p)
65{
66 void **ptrs = heap->ptrs;
67 void *tmp = NULL;
68
69 if (heap->size < heap->max) {
70 /* Add the element to the end */
71 heap->ptrs[heap->size++] = p;
72 /* rebalance */
73 heapify(heap, 0);
74 return NULL;
75 }
76
77 /*
78 * Full. We need to replace the largest (if we are
79 * smaller or equal to this element).
80 */
81 if (heap->gt(ptrs[0], p)) {
82 tmp = ptrs[0];
83 ptrs[0] = p;
84 /* rebalance */
85 heapify(heap, 0);
86 } else {
87 tmp = p;
88 }
89 return tmp;
90}
91
f3bc08c5
MD
92void *heap_remove(struct ptr_heap *heap)
93{
94 void **ptrs = heap->ptrs;
95
96 switch (heap->size) {
97 case 0:
98 return NULL;
99 case 1:
100 heap->size = 0;
101 return ptrs[0];
102 }
103
104 /* Shrink, replace the current max by previous last entry and heapify */
105 return heap_replace_max(heap, ptrs[--heap->size]);
106}
107
108void *heap_cherrypick(struct ptr_heap *heap, void *p)
109{
110 void **ptrs = heap->ptrs;
111 size_t pos, size = heap->size;
112
113 for (pos = 0; pos < size; pos++)
114 if (ptrs[pos] == p)
115 goto found;
116 return NULL;
117found:
118 if (heap->size == 1) {
119 heap->size = 0;
120 return ptrs[0];
121 }
122 /*
123 * Replace p with previous last entry and heapify.
124 */
125 ptrs[pos] = ptrs[--heap->size];
126 heapify(heap, pos);
127 return p;
128}
This page took 0.027726 seconds and 4 git commands to generate.