commit 752d9ce8b51a672a0355c537ff13a3b958e84d88 Author: hladu357 Date: Wed Jun 5 14:40:59 2024 +0200 basic insert diff --git a/trie/Makefile b/trie/Makefile new file mode 100644 index 0000000..fda9e48 --- /dev/null +++ b/trie/Makefile @@ -0,0 +1,2 @@ +trie: trie.c trie.h + gcc trie.c -Wall -pedantic -std=c89 -o trie \ No newline at end of file diff --git a/trie/trie.c b/trie/trie.c new file mode 100644 index 0000000..f143e45 --- /dev/null +++ b/trie/trie.c @@ -0,0 +1,107 @@ +#include "trie.h" + +#define INPUT_FILE "../data/routing-data" +#define READ_MODE "r" +#define GET_BIT(key, bit) (( key[ bit / (sizeof(unsigned) * 8) ] & (1 << ((sizeof(unsigned) * 8 - 1) - (bit % (sizeof(unsigned) * 8)))) ) != 0 ) + + +trie_node_t create_node() { + trie_node_t ret = calloc(1, sizeof(struct trie_node)); /* sets null childs and invalid */ + return ret; +} + +trie_holder_t create_holder() { + trie_holder_t ret = malloc(sizeof(struct trie_holder)); + ret->_size = 0; + ret->_root = create_node(); + return ret; +} + +int trie_insert(trie_holder_t t, const unsigned key[4], int val, int mask) { + trie_node_t iter = t->_root; + trie_node_t* next = &t->_root; + int i = 0; + + for (;i <= 128 - mask; ++i) { + if (!*(next = GET_BIT(key, i) ? &iter->_l : &iter->_r)) + *next = create_node(); + + iter = *next; + } + + if (iter->_rule_valid == VALID_RULE) { + printf("WARNING: conflicting rule %x:%x:%x:%x", key[0], key[1], key[2], key[3]); + printf("/%d %d\n", mask, val); + return 0; + } + + iter->_rule_valid = VALID_RULE; + iter->_rule = val; + + /* printf("inserted rule: %x:%x:%x:%x", key[0], key[1], key[2], key[3]); */ + /* printf("/%d %d\n", mask, val); */ + return 1; +} + +int trie_search(trie_holder_t t, const unsigned key[4]) { + return 0; +} + + +/*------------------------------------------------------------*/ + + +int parse_line(unsigned key[4], int* val, int* mask, FILE* f) { /*! assumes only good input */ + + unsigned short* tmp = (unsigned short*)key; + memset(tmp, 0, sizeof(short[8])); + + fscanf(f, "%hx:%hx:%hx:%hx:%hx:%hx:%hx:%hx", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5], &tmp[6], &tmp[7]); + if (feof(f)) return 0; /* ends with newline */ + while (fgetc(f) != '/'); + + fscanf(f, "%d %d", mask, val); + + /* printf("Loaded address: %x:%x:%x:%x", key[0], key[1], key[2], key[3]); */ + /* printf("/%d %d\n", *mask, *val); */ + + return !feof(f); +} + +int load_input(trie_holder_t t) { + int val; + int mask; + unsigned key[4]; + + FILE* f; + int cnt = 0; + + if (!(f = fopen(INPUT_FILE, READ_MODE))) + perror("cant open input file"); + + while (parse_line(key, &val, &mask, f)) { + trie_insert(t, key, val, mask); + ++cnt; + } + return cnt; +} + +int main() { + trie_holder_t t = create_holder(); + + /* + unsigned key[4] = {8927349, 9872346, 898097878, 928398629}; + int i; + 00000000100010000011100001110101 00000000100101101010001111011010 00110101100001111110001011010110 00110111010101100011110100100101 + 00000000100010000011100001110101 00000000100101101010001111011010 00110101100001111110001011010110 00110111010101100011110100100101 + + for (i = 0; i < 128; ++i) { + printf("%d", GET_BIT(key, i)); + } + printf("\n"); + return 0; + */ + + printf("Loaded %d rules\n", load_input(t) ); + return 0; +} \ No newline at end of file diff --git a/trie/trie.h b/trie/trie.h new file mode 100644 index 0000000..d0f75bf --- /dev/null +++ b/trie/trie.h @@ -0,0 +1,44 @@ +#ifndef TRIE_HEADER_843762518432898246756 +#define TRIE_HEADER_843762518432898246756 + +#include "stdio.h" +#include "stdlib.h" +#include "string.h" + +union ipv6 { + unsigned short s[8]; + unsigned long l[2]; +}; + +#define VALID_RULE 1 +#define INVALID_RULE 0 + +struct trie_node { + struct trie_node* _l; + struct trie_node* _r; + int _rule:31; + unsigned _rule_valid:1; +}; + +struct trie_holder { + struct trie_node* _root; + size_t _size; +}; + +typedef struct trie_node* trie_node_t; +typedef struct trie_holder* trie_holder_t; +typedef union ipv6 ipv6_t; +typedef int rule_t; + +struct trie_holder* create_holder(); +struct trie_node* create_node(); + +int destory_holder(struct trie_holder*); +int destory_node(struct trie_node*); + +int trie_insert(struct trie_holder*, const unsigned key[4], int val, int mask); +rule_t trie_search(struct trie_holder*, const unsigned key[4]); + + + +#endif \ No newline at end of file