From 71c633f4798c7554f3889071b85800522595029a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Kn=C3=BCttel?= Date: Wed, 26 Sep 2018 13:18:37 +0200 Subject: [PATCH] added method dispatcher --- method_dispatcher.c | 120 ++++++++++++++++++++++++++++++++++ method_dispatcher.h | 61 +++++++++++++++++ test/Makefile | 14 ++++ test/method_dispatcher | Bin 0 -> 13296 bytes test/test_method_dispatcher.c | 51 +++++++++++++++ 5 files changed, 246 insertions(+) create mode 100644 method_dispatcher.c create mode 100644 method_dispatcher.h create mode 100644 test/Makefile create mode 100755 test/method_dispatcher create mode 100644 test/test_method_dispatcher.c diff --git a/method_dispatcher.c b/method_dispatcher.c new file mode 100644 index 0000000..90e4fed --- /dev/null +++ b/method_dispatcher.c @@ -0,0 +1,120 @@ +#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; +} + diff --git a/method_dispatcher.h b/method_dispatcher.h new file mode 100644 index 0000000..96a04f6 --- /dev/null +++ b/method_dispatcher.h @@ -0,0 +1,61 @@ +#ifndef bci_method_dispatcher_h__ +#define bci_method_dispatcher_h__ + +#include +#include "base.h" + +typedef struct dispatch_tree_node_s +{ + struct dispatch_tree_node_s * higher; + struct dispatch_tree_node_s * lower; + uint16_t word; + bci_core_method_t method; +} * dispatch_tree_node_t; + +typedef struct dispatch_tree_s +{ + dispatch_tree_node_t root; +} * dispatch_tree_t; + +dispatch_tree_t dispatch_tree_t_new(void); +/* + * This deletes the tree and will invoke dispatch_tree_node_t_del on + * tree->root (which will delete all the other nodes recursively). + * If you want to keep nodes you have to explicityl remove the reference to + * them by setting them to NULL. + * */ +void dispatch_tree_t_del(dispatch_tree_t tree); + + +dispatch_tree_node_t dispatch_tree_node_t_new(uint16_t word + , bci_core_method_t method); +/* + * This deletes the node an will invoke dispatch_tree_node_t_del on + * node->higher and node->lower. If you want to keep those nodes + * you have to explicitly clear the reference by setting them to NULL. + * */ +void dispatch_tree_node_t_del(dispatch_tree_node_t node); + + +/* + * Insert a new key-value-pair into the tree. + * + * Return codes: + * 0: OK + * 1: out of memory + * 2: key already in tree + * */ +char dispatch_tree_t_insert(dispatch_tree_t tree + , uint16_t word + , bci_core_method_t method); + +// TODO: +// Figure out if that function is actually useful. +// Maybe manually inserting the methods in a good order +// is better. +// +//dispatch_tree_t optimize(dispatch_tree_t tree); + +bci_core_method_t dispatch_tree_t_dispatch(dispatch_tree_t tree + , uint16_t word); +#endif diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..7997126 --- /dev/null +++ b/test/Makefile @@ -0,0 +1,14 @@ +CC=gcc + +all: test_method_dispatcher + +method_dispatcher: clean + $(CC) ../method_dispatcher.c test_method_dispatcher.c -o method_dispatcher + +test_method_dispatcher: method_dispatcher + valgrind ./method_dispatcher + + + +clean: + -rm method_dispatcher diff --git a/test/method_dispatcher b/test/method_dispatcher new file mode 100755 index 0000000000000000000000000000000000000000..722927d6859dc0ce1721b8f7d972da01e209cc89 GIT binary patch literal 13296 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 literal 0 HcmV?d00001 diff --git a/test/test_method_dispatcher.c b/test/test_method_dispatcher.c new file mode 100644 index 0000000..563d888 --- /dev/null +++ b/test/test_method_dispatcher.c @@ -0,0 +1,51 @@ +#include +#include "../method_dispatcher.h" + +char m1(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_reg, uint16_t * reg[10], bci_stack_t * stack); +char m2(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_reg, uint16_t * reg[10], bci_stack_t * stack); +char m3(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_reg, uint16_t * reg[10], bci_stack_t * stack); +char m4(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_reg, uint16_t * reg[10], bci_stack_t * stack); +char m5(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_reg, uint16_t * reg[10], bci_stack_t * stack); + +int main(void) +{ + printf("sizeof struct dispatch_tree_node_s: %zd\n", sizeof(struct dispatch_tree_node_s)); + dispatch_tree_t tree = dispatch_tree_t_new(); + + dispatch_tree_t_insert(tree, 3 << 6, m3); + dispatch_tree_t_insert(tree, 2 << 6, m2); + dispatch_tree_t_insert(tree, 1 << 6, m1); + dispatch_tree_t_insert(tree, 4 << 6, m4); + dispatch_tree_t_insert(tree, 5 << 6, m5); + + int i; + for(i = 1; i < 6; i++) + { + dispatch_tree_t_dispatch(tree, i << 6)(i, i << 6, NULL, NULL, NULL, NULL); + } + dispatch_tree_t_del(tree); + return 0; +} + + + +char m1(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_register, uint16_t * reg[10], bci_stack_t * stack) +{ + printf("m1: %d, %d\n", small_arg, arg); +} +char m2(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_register, uint16_t * reg[10], bci_stack_t * stack) +{ + printf("m2: %d, %d\n", small_arg, arg); +} +char m3(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_register, uint16_t * reg[10], bci_stack_t * stack) +{ + printf("m3: %d, %d\n", small_arg, arg); +} +char m4(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_register, uint16_t * reg[10], bci_stack_t * stack) +{ + printf("m4: %d, %d\n", small_arg, arg); +} +char m5(uint8_t small_arg, uint16_t arg, uint16_t * s_reg, uint16_t * shutdown_register, uint16_t * reg[10], bci_stack_t * stack) +{ + printf("m5: %d, %d\n", small_arg, arg); +}