blob: 6d4965f1beaf52e1e6a16fb1b0306b55fa01e759 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef included_clib_fheap_h
16#define included_clib_fheap_h
17
18/* Fibonacci Heaps Fredman, M. L.; Tarjan (1987).
19 "Fibonacci heaps and their uses in improved network optimization algorithms" */
20
21#include <vppinfra/vec.h>
22
Dave Barachc3799992016-08-15 11:12:27 -040023typedef struct
24{
Ed Warnickecb9cada2015-12-08 15:45:58 -070025 /* Node index of parent. */
26 u32 parent;
27
28 /* Node index of first child. */
29 u32 first_child;
30
31 /* Next and previous nodes in doubly linked list of siblings. */
32 u32 next_sibling, prev_sibling;
33
34 /* Key (distance) for this node. Parent always has key
35 <= than keys of children. */
36 u32 key;
37
38 /* Number of children (as opposed to descendents). */
39 u32 rank;
40
41 u32 is_marked;
42
43 /* Set to one when node is inserted; zero when deleted. */
44 u32 is_valid;
45} fheap_node_t;
46
47#define foreach_fheap_node_sibling(f,ni,first_ni,body) \
48do { \
49 u32 __fheap_foreach_first_ni = (first_ni); \
50 u32 __fheap_foreach_ni = __fheap_foreach_first_ni; \
51 u32 __fheap_foreach_next_ni; \
52 fheap_node_t * __fheap_foreach_n; \
53 if (__fheap_foreach_ni != ~0) \
54 while (1) \
55 { \
56 __fheap_foreach_n = fheap_get_node ((f), __fheap_foreach_ni); \
57 __fheap_foreach_next_ni = __fheap_foreach_n -> next_sibling; \
58 (ni) = __fheap_foreach_ni; \
59 \
60 body; \
61 \
62 /* End of circular list? */ \
63 if (__fheap_foreach_next_ni == __fheap_foreach_first_ni) \
64 break; \
65 \
66 __fheap_foreach_ni = __fheap_foreach_next_ni; \
67 \
68 } \
69} while (0)
70
Dave Barachc3799992016-08-15 11:12:27 -040071typedef struct
72{
Ed Warnickecb9cada2015-12-08 15:45:58 -070073 u32 min_root;
74
75 /* Vector of nodes. */
Dave Barachc3799992016-08-15 11:12:27 -040076 fheap_node_t *nodes;
Ed Warnickecb9cada2015-12-08 15:45:58 -070077
Dave Barachc3799992016-08-15 11:12:27 -040078 u32 *root_list_by_rank;
Ed Warnickecb9cada2015-12-08 15:45:58 -070079
80 u32 enable_validate;
81
82 u32 validate_serial;
83} fheap_t;
84
85/* Initialize empty heap. */
86always_inline void
87fheap_init (fheap_t * f, u32 n_nodes)
88{
Dave Barachc3799992016-08-15 11:12:27 -040089 fheap_node_t *save_nodes = f->nodes;
90 u32 *save_root_list = f->root_list_by_rank;
Ed Warnickecb9cada2015-12-08 15:45:58 -070091
92 memset (f, 0, sizeof (f[0]));
93
94 f->nodes = save_nodes;
95 f->root_list_by_rank = save_root_list;
96
97 vec_validate (f->nodes, n_nodes - 1);
98 vec_reset_length (f->root_list_by_rank);
99
100 f->min_root = ~0;
101}
102
103always_inline void
104fheap_free (fheap_t * f)
105{
106 vec_free (f->nodes);
107 vec_free (f->root_list_by_rank);
108}
109
110always_inline u32
111fheap_find_min (fheap_t * f)
Dave Barachc3799992016-08-15 11:12:27 -0400112{
113 return f->min_root;
114}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700115
116always_inline u32
117fheap_is_empty (fheap_t * f)
Dave Barachc3799992016-08-15 11:12:27 -0400118{
119 return f->min_root == ~0;
120}
Ed Warnickecb9cada2015-12-08 15:45:58 -0700121
122/* Add/delete nodes. */
123void fheap_add (fheap_t * f, u32 ni, u32 key);
124void fheap_del (fheap_t * f, u32 ni);
125
126/* Delete and return minimum. */
127u32 fheap_del_min (fheap_t * f, u32 * min_key);
128
129/* Change key value. */
130void fheap_decrease_key (fheap_t * f, u32 ni, u32 new_key);
131
132#endif /* included_clib_fheap_h */
Dave Barachc3799992016-08-15 11:12:27 -0400133
134/*
135 * fd.io coding-style-patch-verification: ON
136 *
137 * Local Variables:
138 * eval: (c-set-style "gnu")
139 * End:
140 */