diff options
Diffstat (limited to 'vppinfra/vppinfra/fheap.h')
-rw-r--r-- | vppinfra/vppinfra/fheap.h | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/vppinfra/vppinfra/fheap.h b/vppinfra/vppinfra/fheap.h new file mode 100644 index 00000000000..974eb1fc698 --- /dev/null +++ b/vppinfra/vppinfra/fheap.h @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2015 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef included_clib_fheap_h +#define included_clib_fheap_h + +/* Fibonacci Heaps Fredman, M. L.; Tarjan (1987). + "Fibonacci heaps and their uses in improved network optimization algorithms" */ + +#include <vppinfra/vec.h> + +typedef struct { + /* Node index of parent. */ + u32 parent; + + /* Node index of first child. */ + u32 first_child; + + /* Next and previous nodes in doubly linked list of siblings. */ + u32 next_sibling, prev_sibling; + + /* Key (distance) for this node. Parent always has key + <= than keys of children. */ + u32 key; + + /* Number of children (as opposed to descendents). */ + u32 rank; + + u32 is_marked; + + /* Set to one when node is inserted; zero when deleted. */ + u32 is_valid; +} fheap_node_t; + +#define foreach_fheap_node_sibling(f,ni,first_ni,body) \ +do { \ + u32 __fheap_foreach_first_ni = (first_ni); \ + u32 __fheap_foreach_ni = __fheap_foreach_first_ni; \ + u32 __fheap_foreach_next_ni; \ + fheap_node_t * __fheap_foreach_n; \ + if (__fheap_foreach_ni != ~0) \ + while (1) \ + { \ + __fheap_foreach_n = fheap_get_node ((f), __fheap_foreach_ni); \ + __fheap_foreach_next_ni = __fheap_foreach_n -> next_sibling; \ + (ni) = __fheap_foreach_ni; \ + \ + body; \ + \ + /* End of circular list? */ \ + if (__fheap_foreach_next_ni == __fheap_foreach_first_ni) \ + break; \ + \ + __fheap_foreach_ni = __fheap_foreach_next_ni; \ + \ + } \ +} while (0) + +typedef struct { + u32 min_root; + + /* Vector of nodes. */ + fheap_node_t * nodes; + + u32 * root_list_by_rank; + + u32 enable_validate; + + u32 validate_serial; +} fheap_t; + +/* Initialize empty heap. */ +always_inline void +fheap_init (fheap_t * f, u32 n_nodes) +{ + fheap_node_t * save_nodes = f->nodes; + u32 * save_root_list = f->root_list_by_rank; + + memset (f, 0, sizeof (f[0])); + + f->nodes = save_nodes; + f->root_list_by_rank = save_root_list; + + vec_validate (f->nodes, n_nodes - 1); + vec_reset_length (f->root_list_by_rank); + + f->min_root = ~0; +} + +always_inline void +fheap_free (fheap_t * f) +{ + vec_free (f->nodes); + vec_free (f->root_list_by_rank); +} + +always_inline u32 +fheap_find_min (fheap_t * f) +{ return f->min_root; } + +always_inline u32 +fheap_is_empty (fheap_t * f) +{ return f->min_root == ~0; } + +/* Add/delete nodes. */ +void fheap_add (fheap_t * f, u32 ni, u32 key); +void fheap_del (fheap_t * f, u32 ni); + +/* Delete and return minimum. */ +u32 fheap_del_min (fheap_t * f, u32 * min_key); + +/* Change key value. */ +void fheap_decrease_key (fheap_t * f, u32 ni, u32 new_key); + +#endif /* included_clib_fheap_h */ |