You've already forked qlg.tsgz.moe
Init Repo
This commit is contained in:
219
vendor/swoole/src/core/heap.c
vendored
Executable file
219
vendor/swoole/src/core/heap.c
vendored
Executable file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
+----------------------------------------------------------------------+
|
||||
| Swoole |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 2.0 of the Apache license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
| http://www.apache.org/licenses/LICENSE-2.0.html |
|
||||
| If you did not receive a copy of the Apache2.0 license and are unable|
|
||||
| to obtain it through the world-wide-web, please send a note to |
|
||||
| license@swoole.com so we can mail you a copy immediately. |
|
||||
+----------------------------------------------------------------------+
|
||||
| Author: Tianfeng Han <mikan.tenny@gmail.com> |
|
||||
+----------------------------------------------------------------------+
|
||||
*/
|
||||
|
||||
#include "swoole.h"
|
||||
#include "heap.h"
|
||||
|
||||
#define left(i) ((i) << 1)
|
||||
#define right(i) (((i) << 1) + 1)
|
||||
#define parent(i) ((i) >> 1)
|
||||
|
||||
static void swHeap_bubble_up(swHeap *heap, uint32_t i);
|
||||
static uint32_t swHeap_maxchild(swHeap *heap, uint32_t i);
|
||||
static void swHeap_percolate_down(swHeap *heap, uint32_t i);
|
||||
|
||||
swHeap *swHeap_new(size_t n, uint8_t type)
|
||||
{
|
||||
swHeap *heap = sw_malloc(sizeof(swHeap));
|
||||
if (!heap)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
if (!(heap->nodes = sw_malloc((n + 1) * sizeof(void *))))
|
||||
{
|
||||
sw_free(heap);
|
||||
return NULL;
|
||||
}
|
||||
heap->num = 1;
|
||||
heap->size = (n + 1);
|
||||
heap->type = type;
|
||||
return heap;
|
||||
}
|
||||
|
||||
void swHeap_free(swHeap *heap)
|
||||
{
|
||||
sw_free(heap->nodes);
|
||||
sw_free(heap);
|
||||
}
|
||||
|
||||
static sw_inline int swHeap_compare(uint8_t type, uint64_t a, uint64_t b)
|
||||
{
|
||||
if (type == SW_MIN_HEAP)
|
||||
{
|
||||
return a > b;
|
||||
}
|
||||
else
|
||||
{
|
||||
return a < b;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t swHeap_size(swHeap *q)
|
||||
{
|
||||
return (q->num - 1);
|
||||
}
|
||||
|
||||
static uint32_t swHeap_maxchild(swHeap *heap, uint32_t i)
|
||||
{
|
||||
uint32_t child_i = left(i);
|
||||
if (child_i >= heap->num)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
swHeap_node * child_node = heap->nodes[child_i];
|
||||
if ((child_i + 1) < heap->num && swHeap_compare(heap->type, child_node->priority, heap->nodes[child_i + 1]->priority))
|
||||
{
|
||||
child_i++;
|
||||
}
|
||||
return child_i;
|
||||
}
|
||||
|
||||
static void swHeap_bubble_up(swHeap *heap, uint32_t i)
|
||||
{
|
||||
swHeap_node *moving_node = heap->nodes[i];
|
||||
uint32_t parent_i;
|
||||
|
||||
for (parent_i = parent(i);
|
||||
(i > 1) && swHeap_compare(heap->type, heap->nodes[parent_i]->priority, moving_node->priority);
|
||||
i = parent_i, parent_i = parent(i))
|
||||
{
|
||||
heap->nodes[i] = heap->nodes[parent_i];
|
||||
heap->nodes[i]->position = i;
|
||||
}
|
||||
|
||||
heap->nodes[i] = moving_node;
|
||||
moving_node->position = i;
|
||||
}
|
||||
|
||||
static void swHeap_percolate_down(swHeap *heap, uint32_t i)
|
||||
{
|
||||
uint32_t child_i;
|
||||
swHeap_node *moving_node = heap->nodes[i];
|
||||
|
||||
while ((child_i = swHeap_maxchild(heap, i))
|
||||
&& swHeap_compare(heap->type, moving_node->priority, heap->nodes[child_i]->priority))
|
||||
{
|
||||
heap->nodes[i] = heap->nodes[child_i];
|
||||
heap->nodes[i]->position = i;
|
||||
i = child_i;
|
||||
}
|
||||
|
||||
heap->nodes[i] = moving_node;
|
||||
moving_node->position = i;
|
||||
}
|
||||
|
||||
swHeap_node* swHeap_push(swHeap *heap, uint64_t priority, void *data)
|
||||
{
|
||||
void *tmp;
|
||||
uint32_t i;
|
||||
uint32_t newsize;
|
||||
|
||||
if (heap->num >= heap->size)
|
||||
{
|
||||
newsize = heap->size * 2;
|
||||
if (!(tmp = sw_realloc(heap->nodes, sizeof(void *) * newsize)))
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
heap->nodes = tmp;
|
||||
heap->size = newsize;
|
||||
}
|
||||
|
||||
swHeap_node *node = sw_malloc(sizeof(swHeap_node));
|
||||
if (!node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
node->priority = priority;
|
||||
node->data = data;
|
||||
i = heap->num++;
|
||||
heap->nodes[i] = node;
|
||||
swHeap_bubble_up(heap, i);
|
||||
return node;
|
||||
}
|
||||
|
||||
void swHeap_change_priority(swHeap *heap, uint64_t new_priority, void* ptr)
|
||||
{
|
||||
swHeap_node *node = ptr;
|
||||
uint32_t pos = node->position;
|
||||
uint64_t old_pri = node->priority;
|
||||
|
||||
node->priority = new_priority;
|
||||
if (swHeap_compare(heap->type, old_pri, new_priority))
|
||||
{
|
||||
swHeap_bubble_up(heap, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
swHeap_percolate_down(heap, pos);
|
||||
}
|
||||
}
|
||||
|
||||
int swHeap_remove(swHeap *heap, swHeap_node *node)
|
||||
{
|
||||
uint32_t pos = node->position;
|
||||
heap->nodes[pos] = heap->nodes[--heap->num];
|
||||
|
||||
if (swHeap_compare(heap->type, node->priority, heap->nodes[pos]->priority))
|
||||
{
|
||||
swHeap_bubble_up(heap, pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
swHeap_percolate_down(heap, pos);
|
||||
}
|
||||
return SW_OK;
|
||||
}
|
||||
|
||||
void *swHeap_pop(swHeap *heap)
|
||||
{
|
||||
swHeap_node *head;
|
||||
if (!heap || heap->num == 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
head = heap->nodes[1];
|
||||
heap->nodes[1] = heap->nodes[--heap->num];
|
||||
swHeap_percolate_down(heap, 1);
|
||||
|
||||
void *data = head->data;
|
||||
sw_free(head);
|
||||
return data;
|
||||
}
|
||||
|
||||
void *swHeap_peek(swHeap *heap)
|
||||
{
|
||||
if (heap->num == 1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
swHeap_node *node = heap->nodes[1];
|
||||
if (!node)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return node->data;
|
||||
}
|
||||
|
||||
void swHeap_print(swHeap *heap)
|
||||
{
|
||||
int i;
|
||||
for(i = 1; i < heap->num; i++)
|
||||
{
|
||||
printf("#%d\tpriority=%ld, data=%p\n", i, (long)heap->nodes[i]->priority, heap->nodes[i]->data);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user