added method dispatcher
This commit is contained in:
commit
71c633f479
120
method_dispatcher.c
Normal file
120
method_dispatcher.c
Normal file
|
@ -0,0 +1,120 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
61
method_dispatcher.h
Normal file
61
method_dispatcher.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef bci_method_dispatcher_h__
|
||||||
|
#define bci_method_dispatcher_h__
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#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
|
14
test/Makefile
Normal file
14
test/Makefile
Normal file
|
@ -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
|
BIN
test/method_dispatcher
Executable file
BIN
test/method_dispatcher
Executable file
Binary file not shown.
51
test/test_method_dispatcher.c
Normal file
51
test/test_method_dispatcher.c
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#include <stdio.h>
|
||||||
|
#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);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user