19#ifndef __ORDERED_COVERING_H__
20#define __ORDERED_COVERING_H__
27#include "../common/routing_table.h"
30typedef struct _sets_t {
40 const unsigned int generality) {
42 const unsigned int g_m_1 = generality - 1;
52 while ((bottom < pos) && (pos < top) && (count_xs != g_m_1)) {
53 if (count_xs < g_m_1) {
60 pos = bottom + (top - bottom) / 2;
70 (count_xs < generality)) {
96 volatile bool *stop_compressing,
bool *changed) {
97 min_goodness = (min_goodness > 0) ? min_goodness : 0;
111 if (*stop_compressing) {
125 for (
unsigned int j = i + 1; j < insertion_index; j++) {
158static void _get_settable(
160 uint32_t *set_to_zero, uint32_t *set_to_one) {
163 uint32_t setable = ~key_mask_get_xs(covered_km) &
key_mask_get_xs(merge_km);
164 unsigned int new_stringency = __builtin_popcount(setable);
166 uint32_t this_set_to_zero = setable & covered_km.
key;
167 uint32_t this_set_to_one = setable & ~covered_km.key;
172 if (new_stringency < *stringency) {
174 *stringency = new_stringency;
175 *set_to_zero = this_set_to_zero;
176 *set_to_one = this_set_to_one;
177 }
else if (new_stringency == *stringency) {
178 *set_to_zero |= this_set_to_zero;
179 *set_to_one |= this_set_to_one;
189static inline __sets_t _get_removables(
190 merge_t *m, uint32_t settable,
bool to_one, __sets_t sets) {
193 for (uint32_t bit = (1 << 31); bit > 0 && sets.best->count != 1;
197 if (!(bit & settable)) {
216 if ((bit & ~km.
mask) || (!to_one && (bit & km.
key)) ||
217 (to_one && (bit & ~km.
key))) {
229 if (sets.best->count == 0 || sets.working->count < sets.best->count) {
232 sets.best = sets.working;
257 bool *failed_by_malloc,
258 volatile bool *stop_compressing) {
259 min_goodness = (min_goodness > 0) ? min_goodness : 0;
263 if (*stop_compressing) {
269 bool covered_entries =
false;
271 unsigned int stringency = 33;
273 uint32_t set_to_zero = 0x0;
275 uint32_t set_to_one = 0x0;
280 int insertion_point =
283 for (
int i = insertion_point;
287 if (*stop_compressing) {
297 covered_entries =
true;
305 while (the_alias_list !=
NULL) {
307 if (*stop_compressing) {
311 for (
unsigned int j = 0; j < the_alias_list->
n_elements;
315 if (*stop_compressing) {
323 covered_entries =
true;
326 &set_to_zero, &set_to_one);
331 the_alias_list = the_alias_list->
next;
337 if (!covered_entries) {
342 if (stringency == 0) {
355 if (sets.best ==
NULL) {
357 *failed_by_malloc =
true;
362 if (sets.working ==
NULL) {
363 log_error(
"failed to alloc sets.working");
364 *failed_by_malloc =
true;
374 log_error(
"failed to init the bitfield best");
375 *failed_by_malloc =
true;
387 log_error(
"failed to init the bitfield working.");
388 *failed_by_malloc =
true;
400 sets = _get_removables(
merge, set_to_zero,
false, sets);
401 sets = _get_removables(
merge, set_to_one,
true, sets);
407 if (*stop_compressing) {
434 if (
merge->entries.count == 1) {
453 volatile bool *stop_compressing) {
459 log_warning(
"failed to initialise the bit_set. throwing response malloc");
460 *failed_by_malloc =
true;
469 log_warning(
"failed to init the merge best. throw response malloc");
470 *failed_by_malloc =
true;
481 log_warning(
"failed to init the merge working. throw response malloc");
482 *failed_by_malloc =
true;
494 log_debug(
"starting search for merge entry");
497 if (*stop_compressing) {
498 log_info(
"closed due to stop request");
524 log_debug(
"starting second search at index %d", i);
527 if (*stop_compressing) {
528 log_info(
"closed due to stop request");
573 bool changed =
false;
638 log_debug(
"new entry k %x mask %x route %x source %x x mergable is %d",
643 int insertion_point =
645 log_debug(
"the insertion point is %d", insertion_point);
648 int reduced_size = 0;
654 if (new_aliases ==
NULL) {
655 log_error(
"failed to malloc new alias list");
656 *failed_by_malloc =
true;
661 bool malloc_success =
663 if (!malloc_success) {
664 log_error(
"failed to malloc new alias list during insert");
665 *failed_by_malloc =
true;
679 log_debug(
"entry %d being processed has key %x or %d, mask %x "
680 "route %x source %x", remove, current->
key_mask.
key,
685 if (remove == insertion_point) {
686 log_debug(
"remove == insert at index %d and insert %d at "
687 "insert point", remove, insert);
702 log_debug(
"not contains at index %d and insert %d at insert point",
715 log_debug(
"merge contains at index %d and insert %d at "
716 "insert point", remove, insert);
721 uint32_t source = current->
source;
738 log_debug(
"at index %d and insert %d not at merge point",
750 log_debug(
"insert point was at end of table, new insert point is %d",
774 int target_length,
bool *failed_by_malloc,
775 volatile bool *stop_compressing) {
777 log_debug(
"n entries before compression is %d",
781 log_info(
"does not need compression.");
793 !*stop_compressing) {
800 &aliases, &
merge, failed_by_malloc, stop_compressing);
802 log_debug(
"failed to do get best merge. "
803 "the number of merge cycles were %d", attempts);
809 unsigned int count =
merge.entries.count;
817 &
merge, &aliases, failed_by_malloc);
819 if (!malloc_success) {
845 if (*stop_compressing) {
846 log_info(
"Asked to stop. reached %d entries over %d attempts",
853 log_info(
"entries after compressed = %d, target_length = %d, stop = %d, "
854 " the number of merge cycles were %d",
Aliases in the routing tree.
static bool aliases_insert(aliases_t *a, key_mask_t key, alias_list_t *value)
Add/overwrite an element into an aliases tree.
static bool alias_list_append(alias_list_t *as, key_mask_t val, uint32_t source)
Append an element to a list.
unsigned int n_elements
Elements in this instance.
struct _alias_list_t * next
Next element in list of lists.
void alias_list_delete(alias_list_t *a)
Delete all elements in an alias list.
static alias_list_t * alias_list_new(unsigned int max_size)
Create a new list on the stack.
key_mask_t key_mask
key_mask of the element
static void alias_list_join(alias_list_t *a, alias_list_t *b)
Append a list to an existing list.
static alias_list_t * aliases_find(aliases_t *a, key_mask_t key)
Retrieve an element from an aliases container.
static bool aliases_contains(aliases_t *a, key_mask_t key)
See if the aliases contain holds an element.
static alias_element_t alias_list_get(alias_list_t *as, unsigned int i)
Get an element from the list.
static void aliases_remove(aliases_t *a, key_mask_t key)
Remove an element from an aliases tree.
static aliases_t aliases_init(void)
Create a new, empty, aliases container.
static void aliases_clear(aliases_t *a)
Remove all elements from an aliases container and free all sub-containers.
bool bit_set_clear(bit_set_t *b)
Empty a bitset entirely.
static bool bit_set_add(bit_set_t *b, unsigned int i)
Add an element to a bitset.
static bool bit_set_contains(bit_set_t *b, unsigned int i)
Test if an element is in a bitset.
static bool bit_set_init(bit_set_t *b, unsigned int length)
Create a new bitset.
static void bit_set_delete(bit_set_t *b)
Destroy a bitset.
SpiNNaker debug header file.
void log_error(const char *message,...)
This function logs errors. Errors usually indicate a serious fault in the program,...
void log_warning(const char *message,...)
This function logs warnings.
void log_debug(const char *message,...)
This function logs debugging messages. This level of message is normally not printed except when the ...
void log_info(const char *message,...)
This function logs informational messages. This is the lowest level of message normally printed.
How to merge routing table entries.
static int merge_goodness(merge_t *merge)
Get the goodness for a merge.
static void merge_clear(merge_t *m)
Clear a merge.
static bool merge_contains(merge_t *m, unsigned int i)
See if an entry is contained within a merge.
static void merge_delete(merge_t *m)
Destroy a merge.
static void merge_remove(merge_t *m, unsigned int i)
Remove an entry from the merge.
static bool merge_init(merge_t *m, uint32_t n_entries_in_table)
Initialise a merge.
static void merge_add(merge_t *m, unsigned int i)
Add an entry to the merge.
merge struct. entries which can be merged
static bool oc_up_check(merge_t *merge, int min_goodness, volatile bool *stop_compressing, bool *changed)
Remove from a merge any entries which would be covered by being existing entries if they were include...
static bool oc_down_check(merge_t *merge, int min_goodness, aliases_t *aliases, bool *failed_by_malloc, volatile bool *stop_compressing)
Remove entries from a merge such that the merge would not cover existing entries positioned below the...
static bool oc_get_best_merge(aliases_t *aliases, merge_t *best, bool *failed_by_malloc, volatile bool *stop_compressing)
Get the best merge which can be applied to a routing table.
static unsigned int oc_get_insertion_point(const unsigned int generality)
Get the index where the routing table entry resulting from a merge should be inserted.
bool minimise_run(int target_length, bool *failed_by_malloc, volatile bool *stop_compressing)
Apply the ordered covering algorithm to a routing table.
static bool oc_merge_apply(merge_t *merge, aliases_t *aliases, bool *failed_by_malloc)
Apply a merge to the table against which it is defined.
static entry_t merge(const entry_t *entry1, const entry_t *entry2)
Merges a single pair of route entries.
key_mask_t key_mask
Key and mask.
uint32_t mask
Mask for the key_mask.
static uint32_t key_mask_get_xs(key_mask_t km)
Get a mask of the Xs in a key_mask.
static unsigned int key_mask_count_xs(key_mask_t km)
Get a count of the Xs in a key_mask.
uint32_t route
Routing direction.
int routing_table_get_n_entries(void)
Get the number of entries in the routing table.
static bool key_mask_intersect(key_mask_t a, key_mask_t b)
Determine if two key_masks would match any of the same keys.
entry_t * routing_table_get_entry(uint32_t entry_id_to_find)
Gets a pointer to where this entry is stored.
uint32_t key
Key for the key_mask.
void routing_table_remove_from_size(int size_to_remove)
updates table stores accordingly.
uint32_t source
Source of packets arriving at this entry.
Holds data for a routing table entry.