]>
git.proxmox.com Git - libgit2.git/blob - src/pqueue.c
2 * Copyright (C) 2009-2012 the libgit2 contributors
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
11 #define left(i) ((i) << 1)
12 #define right(i) (((i) << 1) + 1)
13 #define parent(i) ((i) >> 1)
15 int git_pqueue_init(git_pqueue
*q
, size_t n
, git_pqueue_cmp cmppri
)
19 /* Need to allocate n+1 elements since element 0 isn't used. */
20 q
->d
= git__malloc((n
+ 1) * sizeof(void *));
21 GITERR_CHECK_ALLOC(q
->d
);
24 q
->avail
= q
->step
= (n
+ 1); /* see comment above about n+1 */
31 void git_pqueue_free(git_pqueue
*q
)
37 void git_pqueue_clear(git_pqueue
*q
)
42 size_t git_pqueue_size(git_pqueue
*q
)
44 /* queue element 0 exists but doesn't count since it isn't used. */
49 static void bubble_up(git_pqueue
*q
, size_t i
)
52 void *moving_node
= q
->d
[i
];
54 for (parent_node
= parent(i
);
55 ((i
> 1) && q
->cmppri(q
->d
[parent_node
], moving_node
));
56 i
= parent_node
, parent_node
= parent(i
)) {
57 q
->d
[i
] = q
->d
[parent_node
];
60 q
->d
[i
] = moving_node
;
64 static size_t maxchild(git_pqueue
*q
, size_t i
)
66 size_t child_node
= left(i
);
68 if (child_node
>= q
->size
)
71 if ((child_node
+ 1) < q
->size
&&
72 q
->cmppri(q
->d
[child_node
], q
->d
[child_node
+ 1]))
73 child_node
++; /* use right child instead of left */
79 static void percolate_down(git_pqueue
*q
, size_t i
)
82 void *moving_node
= q
->d
[i
];
84 while ((child_node
= maxchild(q
, i
)) != 0 &&
85 q
->cmppri(moving_node
, q
->d
[child_node
])) {
86 q
->d
[i
] = q
->d
[child_node
];
90 q
->d
[i
] = moving_node
;
94 int git_pqueue_insert(git_pqueue
*q
, void *d
)
102 /* allocate more memory if necessary */
103 if (q
->size
>= q
->avail
) {
104 newsize
= q
->size
+ q
->step
;
105 tmp
= git__realloc(q
->d
, sizeof(void *) * newsize
);
106 GITERR_CHECK_ALLOC(tmp
);
121 void *git_pqueue_pop(git_pqueue
*q
)
125 if (!q
|| q
->size
== 1)
129 q
->d
[1] = q
->d
[--q
->size
];
130 percolate_down(q
, 1);
136 void *git_pqueue_peek(git_pqueue
*q
)
138 if (!q
|| q
->size
== 1)