Skip to content

Commit aab27d8

Browse files
DanPanos
authored andcommitted
Node init, insert, clear, insert paths and unittests
1 parent c97fdb4 commit aab27d8

File tree

5 files changed

+285
-38
lines changed

5 files changed

+285
-38
lines changed

untitled/untitled.iml renamed to NodeTree.iml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
<module type="C++" version="4">
33
<component name="NewModuleRootManager" inherit-compiler-output="true">
44
<exclude-output />
5-
<content url="file://$MODULE_DIR$" />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
7+
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
8+
</content>
69
<orderEntry type="jdk" jdkName="Cpp SDK" jdkType="CppSdk" />
710
<orderEntry type="sourceFolder" forTests="false" />
811
</component>

src/node.c

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <fnmatch.h>
5+
#include "node.h"
6+
7+
char** match_entries(char **keys, char *query) {
8+
char **matched_entries;
9+
size_t i = 0, j = 0;
10+
char *key = keys[i];
11+
while (key) {
12+
if (fnmatch(query, key, 0) == 0) {
13+
matched_entries[j] = key;
14+
j++;
15+
}
16+
i++;
17+
key = keys[i];
18+
}
19+
matched_entries[j+1] = NULL;
20+
return matched_entries;
21+
}
22+
23+
void print_index(struct Node *node) {
24+
if (node->children_i > 0) {
25+
for (size_t i = 0; i < node->children_i; i++) {
26+
print_index(&node->children[i]);
27+
}
28+
}
29+
printf("Node %s\n", node->name);
30+
}
31+
32+
struct Node* clear(struct Node *node) {
33+
if(!node) return node;
34+
if (node->children_i > 0) {
35+
for (size_t i = 0; i < node->children_i; i++) {
36+
clear(&node->children[i]);
37+
}
38+
}
39+
printf("Freeing node %s children\n", node->name);
40+
free(node->children);
41+
node->children = NULL;
42+
node->children_i = 0;
43+
node->children_size = 0;
44+
// Clear root node if all sub-tree children have been cleared
45+
if(node && strcmp(node->name, "root") == 0) {
46+
free(node);
47+
node = NULL;
48+
return node;
49+
}
50+
}
51+
52+
struct Node* insert(struct Node *parent, char *path) {
53+
if (!parent->children) {
54+
parent->children = calloc(parent->children_size, sizeof(struct Node));
55+
}
56+
if (parent->children_i == parent->children_size) {
57+
parent->children_size *= 2;
58+
printf("Resizing children of %s to %zu\n", parent->name, parent->children_size);
59+
struct Node *new_children = realloc(parent->children, parent->children_size * sizeof(struct Node));
60+
if (new_children) {
61+
parent->children = new_children;
62+
memset(&parent->children[parent->children_i], 0,
63+
sizeof(struct Node) * (parent->children_size - parent->children_i));
64+
}
65+
else return NULL;
66+
}
67+
parent->children[parent->children_i].name = path;
68+
parent->children[parent->children_i].children_i = 0;
69+
parent->children[parent->children_i].children_size = 1;
70+
printf("Inserted %s to %s\n", parent->children[parent->children_i].name, parent->name);
71+
parent->children_i++;
72+
return &parent->children[parent->children_i-1];
73+
}
74+
75+
struct Node* name_is_child(struct Node *node, char *name) {
76+
struct Node *child;
77+
for (int i=0; i<node->children_i; i++) {
78+
child = &node->children[i];
79+
if (strcmp(child->name, name) == 0) return child;
80+
}
81+
return NULL;
82+
}
83+
84+
85+
int insert_str(struct Node *parent, char *path) {
86+
if (!path) return 0;
87+
char *token, *string, *tofree;
88+
tofree = string = strdup(path);
89+
token = strsep(&string, ".");
90+
if (token) {
91+
printf("Inserting node %s to parent %s\n", token, parent->name);
92+
insert(parent, token);
93+
struct Node *node = &parent->children[parent->children_i];
94+
return insert_str(node, string);
95+
}
96+
free(tofree);
97+
}
98+
99+
struct Node* build_index(char *paths[]) {
100+
struct Node *root = malloc(sizeof(struct Node));
101+
root->name = "root";
102+
root->children_i = 0;
103+
root->children_size = 1;
104+
root->children = NULL;
105+
struct Node *node, *temp = NULL;
106+
temp = root;
107+
size_t i = 0;
108+
char *path = paths[i];
109+
while (path) {
110+
node = insert(temp, path);
111+
i++;
112+
path = paths[i];
113+
temp = node;
114+
}
115+
return root;
116+
}
117+
118+
void insert_paths(struct Node *node, char *paths[]) {
119+
size_t i = 0;
120+
char *path = paths[i];
121+
struct Node *child;
122+
while (path) {
123+
child = name_is_child(node, path);
124+
if (!child) {
125+
child = insert(node, path);
126+
}
127+
else {
128+
printf("Name %s already child of %s\n", path, node->name);
129+
}
130+
node = child;
131+
i++;
132+
path = paths[i];
133+
}
134+
}
135+
136+
struct Node* init_node(char *name) {
137+
struct Node *node = malloc(sizeof(struct Node));
138+
node->name = "root";
139+
node->children_i = 0;
140+
node->children_size = 1;
141+
node->children = NULL;
142+
return node;
143+
}
144+
145+
int is_leaf(struct Node *parent) {
146+
if (!parent) return 0;
147+
return parent->children_i == 0;
148+
}
149+
150+
/*
151+
152+
void insert_all_paths(struct Node *root, char **paths) {
153+
if(!paths) return;
154+
size_t i = 0;
155+
size_t j = 0;
156+
char *sub_paths = paths[i];
157+
char *path = sub_paths[j];
158+
while(path) {
159+
printf("%s\n", path);
160+
}
161+
}*/

src/node.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef NODE_H
2+
#define NODE_H
3+
4+
#define NullNode(...) { .name = NULL, .children_i = 0, .children_size = 1, .children = NULL, ## __VA_ARGS__ }
5+
6+
struct Node {
7+
size_t children_i;
8+
size_t children_size;
9+
char *name;
10+
struct Node *children;
11+
};
12+
13+
void print_index(struct Node *node);
14+
struct Node* clear(struct Node *node);
15+
struct Node* insert(struct Node *parent, char *path);
16+
struct Node* name_is_child(struct Node *node, char *name);
17+
int insert_str(struct Node *parent, char *path);
18+
struct Node* build_index(char *paths[]);
19+
void insert_paths(struct Node *node, char *paths[]);
20+
struct Node* init_node(char *name);
21+
int is_leaf(struct Node *parent);
22+
char** match_entries(char **keys, char *query);
23+
24+
#endif /* NODE_H */

tests/test_node.c

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <check.h>
4+
#include "../src/node.h"
5+
6+
START_TEST(test_create_index) {
7+
8+
struct Node *root = init_node("root");
9+
ck_assert_int_eq(root->children_i, 0);
10+
ck_assert_str_eq(root->name, "root");
11+
root = clear(root);
12+
// ck_assert(!root);
13+
}
14+
END_TEST
15+
16+
void test_node_children(struct Node *parent, char **name) {
17+
while (*name) {
18+
printf("Checking name %s\n", *name);
19+
struct Node *child = name_is_child(parent, *name);
20+
ck_assert(child != NULL);
21+
ck_assert_str_eq(child->name, *name);
22+
parent = child;
23+
name++;
24+
}
25+
}
26+
27+
START_TEST(test_create_index_tree) {
28+
char *paths[] = {"b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "b9", NULL};
29+
struct Node *root = init_node("root");
30+
insert_paths(root, paths);
31+
ck_assert_int_eq(root->children_i, 1);
32+
for (size_t i = 0; i < 1; i++) {
33+
ck_assert_int_eq(root->children[i].children_i, 1);
34+
}
35+
char *new_paths[] = {"b1", "b22", "b3", "b44", "b5", "b66", "b7", "b88", "b9", NULL};
36+
insert_paths(root, new_paths);
37+
for (size_t i = 0; i < 1; i++) {
38+
if (i+1 % 2 == 1) {
39+
ck_assert_int_eq(root->children[i].children_i, 2);
40+
}
41+
else if (i+1 % 2 == 0) {
42+
ck_assert_int_eq(root->children[i].children_i, 1);
43+
}
44+
}
45+
ck_assert(!is_leaf(root));
46+
47+
// Check children
48+
test_node_children(root, &paths[0]);
49+
test_node_children(root, &new_paths[0]);
50+
51+
// Clearing
52+
root = clear(root);
53+
ck_assert(!root);
54+
}
55+
END_TEST
56+
57+
START_TEST(test_match_entries) {
58+
char *keys[] = {"b1", "b2", "b3", "b4", NULL};
59+
char **matches = match_entries(keys, "b*");
60+
size_t i = 0;
61+
char *key = keys[i];
62+
while (key) {
63+
ck_assert_str_eq(matches[i], key);
64+
i++;
65+
key = keys[i];
66+
}
67+
}
68+
END_TEST
69+
70+
Suite * node_suite(void)
71+
{
72+
Suite *s;
73+
TCase *tc_core;
74+
s = suite_create("node");
75+
/* Core test case */
76+
tc_core = tcase_create("Core");
77+
tcase_add_test(tc_core, test_create_index);
78+
tcase_add_test(tc_core, test_create_index_tree);
79+
// tcase_add_test(tc_core, test_match_entries);
80+
suite_add_tcase(s, tc_core);
81+
return s;
82+
}
83+
84+
int main(void) {
85+
int number_failed;
86+
Suite *s;
87+
SRunner *sr;
88+
89+
s = node_suite();
90+
sr = srunner_create(s);
91+
92+
srunner_run_all(sr, CK_VERBOSE);
93+
number_failed = srunner_ntests_failed(sr);
94+
srunner_free(sr);
95+
return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
96+
}

untitled/node.c

Lines changed: 0 additions & 37 deletions
This file was deleted.

0 commit comments

Comments
 (0)