1 /* pq.c - priority queue */
3 /* Copyright (C) 2007 Keith Rarick and Philotic Inc.
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "tube.h" /* hack to make cpp happy */
27 pq_init(pq q
, job_cmp_fn cmp
)
50 unsigned int ncap
= q
->cap
<< 1 ? : 1;
52 nheap
= malloc(ncap
* sizeof(job
));
55 if (q
->heap
) memcpy(nheap
, q
->heap
, q
->used
* sizeof(job
));
62 swap(pq q
, unsigned int a
, unsigned int b
)
67 q
->heap
[a
] = q
->heap
[b
];
71 #define PARENT(i) (((i-1))>>1)
72 #define CHILD_LEFT(i) (((i)<<1)+1)
73 #define CHILD_RIGHT(i) (((i)<<1)+2)
76 cmp(pq q
, unsigned int a
, unsigned int b
)
78 return q
->cmp(q
->heap
[a
], q
->heap
[b
]);
82 bubble_up(pq q
, unsigned int k
)
88 if (cmp(q
, p
, k
) <= 0) return;
94 bubble_down(pq q
, unsigned int k
)
102 if (l
< q
->used
&& cmp(q
, l
, k
) < 0) s
= l
;
103 if (r
< q
->used
&& cmp(q
, r
, s
) < 0) s
= r
;
104 if (s
== k
) return; /* already satisfies the heap property */
110 /* assumes there is at least one item in the queue */
114 q
->heap
[0] = q
->heap
[--q
->used
];
115 if (q
->used
) bubble_down(q
, 0);
123 if (q
->used
>= q
->cap
) pq_grow(q
);
124 if (q
->used
>= q
->cap
) return 0;
138 if (q
->used
== 0) return NULL
;
148 if (q
->used
== 0) return NULL
;
153 pq_find(pq q
, unsigned long long int id
)
157 for (i
= 0; i
< q
->used
; i
++) if (q
->heap
[i
]->id
== id
) return q
->heap
[i
];