#include #include "method_dispatcher.h" dispatch_tree_t dispatch_tree_t_new(void) { dispatch_tree_t tree = malloc(sizeof(struct dispatch_tree_s)); tree->root = NULL; return tree; } void dispatch_tree_t_del(dispatch_tree_t tree) { dispatch_tree_node_t_del(tree->root); free(tree); } dispatch_tree_node_t dispatch_tree_node_t_new(uint16_t word , bci_core_method_t method) { dispatch_tree_node_t node = malloc(sizeof(struct dispatch_tree_node_s)); node->higher = NULL; node->lower = 0; node->method = method; node->word = word; return node; } void dispatch_tree_node_t_del(dispatch_tree_node_t node) { if(node->higher) { dispatch_tree_node_t_del(node->higher); } if(node->lower) { dispatch_tree_node_t_del(node->lower); } free(node); } char dispatch_tree_t_insert(dispatch_tree_t tree , uint16_t word , bci_core_method_t method) { dispatch_tree_node_t new_node = dispatch_tree_node_t_new(word, method); if(!new_node) { return 1; } // explicitly handle empty tree if(!tree->root) { tree->root = new_node; return 0; } // non-empty tree dispatch_tree_node_t this_node = tree->root; dispatch_tree_node_t parent_node = NULL; // search for place do { parent_node = this_node; if(parent_node->word < word) { this_node = parent_node->higher; continue; } if(parent_node->word > word) { this_node = parent_node->lower; continue; } if(parent_node->word == word) { // we already have that key. return 2; } } while(this_node); if(parent_node->word < word) { parent_node->higher = new_node; } if(parent_node->word > word) { parent_node->lower = new_node; } return 0; } bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree , uint16_t word) { dispatch_tree_node_t this_node = tree->root; while(this_node) { if(this_node->word < word) { this_node = this_node->higher; continue; } if(this_node->word > word) { this_node = this_node->lower; continue; } if(this_node->word == word) { return this_node->method; } } return NULL; } dispatch_tree_autoinserter_t dispatch_tree_autoinserter_t_new(dispatch_tree_t tree) { dispatch_tree_autoinserter_t autoinserter = malloc( sizeof(struct dispatch_tree_autoinserter_s)); if(!autoinserter) { return NULL; } autoinserter->mayor = 2; autoinserter->minor = 1; autoinserter->tree = tree; return autoinserter; } void dispatch_tree_autoinserter_t_del(dispatch_tree_autoinserter_t autoinserter) { free(autoinserter); } uint16_t dispatch_tree_autoinserter_t_insert( dispatch_tree_autoinserter_t autoinserter , bci_core_method_t method) { uint16_t opcode = 0b1111111111; opcode *= autoinserter->minor; opcode /= autoinserter->mayor; opcode <<= 6; dispatch_tree_t_insert(autoinserter->tree, opcode, method); autoinserter->minor = (autoinserter->minor + 2) % autoinserter->mayor; if(autoinserter->minor == 1) { autoinserter->mayor *= 2; } return opcode; }