UbixOS  2.0
kern_trie.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2018 The UbixOS Project.
3  * All rights reserved.
4  *
5  * This was developed by Christopher W. Olsen for the UbixOS Project.
6  *
7  * Redistribution and use in source and binary forms, with or without modification, are permitted
8  * provided that the following conditions are met:
9  *
10  * 1) Redistributions of source code must retain the above copyright notice, this list of
11  * conditions, the following disclaimer and the list of authors.
12  * 2) Redistributions in binary form must reproduce the above copyright notice, this list of
13  * conditions, the following disclaimer and the list of authors in the documentation and/or
14  * other materials provided with the distribution.
15  * 3) Neither the name of the UbixOS Project nor the names of its contributors may be used to
16  * endorse or promote products derived from this software without specific prior written
17  * permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
20  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
21  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <sys/types.h>
30 #include <lib/kmalloc.h>
31 #include <lib/kern_trie.h>
32 
33 struct Trie *new_trieNode() {
34 
35  struct Trie *node = (struct Trie *) kmalloc(sizeof(struct Trie));
36 
37  node->isLeaf = 0;
38 
39  for (int i = 0; i < CHAR_SIZE; i++)
40  node->character[i] = NULL;
41 
42  return (node);
43 }
44 
45 // Insert Trie
46 void insert_trieNode(struct Trie **head, char* str, void *e) {
47 
48  // start from root node
49  struct Trie* curr = *head;
50 
51  while (*str) {
52 
53  // create a new node if path doesn't exists
54  if (curr->character[*str - 'a'] == NULL) {
55  curr->character[*str - 'a'] = new_trieNode();
56  }
57 
58  // go to next node
59  curr = curr->character[*str - 'a'];
60  // move to next character
61  str++;
62  }
63 
64  curr->e = e;
65  // mark current node as leaf
66  curr->isLeaf = 1;
67 }
68 
69 
70 struct Trie *search_trieNode(struct Trie *head, char *str) {
71 
72  // return 0 if Trie is empty
73  if (head == NULL || str == NULL)
74  return (0);
75 
76  struct Trie *curr = head;
77 
78  while (*str) {
79 
80  // go to next node
81  curr = curr->character[*str - 'a'];
82 
83  // if string is invalid (reached end of path in Trie)
84  if (curr == NULL)
85  return (0);
86 
87  // move to next character
88  str++;
89  }
90 
91  // if current node is a leaf and we have reached the
92  // end of the string, return 1
93  return (curr);
94 }
95 
96 
97 
98 // Recursive function to delete a string in Trie
99 int delete_trieNode(struct Trie **curr, char *str) {
100 
101  // return if Trie is empty
102  if (*curr == NULL)
103  return (0);
104 
105  // if we have not reached the end of the string
106  if (*str) {
107  // recurse for the node corresponding to next character in
108  // the string and if it returns 1, delete current node
109  // (if it is non-leaf)
110  if (*curr != NULL && (*curr)->character[*str - 'a'] != NULL && deletion(&((*curr)->character[*str - 'a']), str + 1) && (*curr)->isLeaf == 0) {
111  if (!haveChildren(*curr)) {
112  free(*curr);
113  (*curr) = NULL;
114  return (1);
115  }
116  else {
117  return (0);
118  }
119  }
120  }
121 
122  // if we have reached the end of the string
123  if (*str == '\0' && (*curr)->isLeaf) {
124  // if current node is a leaf node and don't have any children
125  if (!haveChildren(*curr)) {
126  free(*curr); // delete current node
127  (*curr) = NULL;
128  return (1); // delete non-leaf parent nodes
129  }
130 
131  // if current node is a leaf node and have children
132  else {
133  // mark current node as non-leaf node (DON'T DELETE IT)
134  (*curr)->isLeaf = 0;
135  return (0); // don't delete its parent nodes
136  }
137  }
138 
139  return (0);
140 }
141 
142 // returns 1 if given node has any children
143 int haveChildren(struct Trie* curr) {
144  for (int i = 0; i < CHAR_SIZE; i++)
145  if (curr->character[i])
146  return (1); // child found
147 
148  return (0);
149 }
delete_trieNode
int delete_trieNode(struct Trie **curr, char *str)
Definition: kern_trie.c:99
haveChildren
int haveChildren(struct Trie *curr)
Definition: kern_trie.c:143
Trie::character
struct Trie * character[26]
Definition: kern_trie.h:38
types.h
insert_trieNode
void insert_trieNode(struct Trie **head, char *str, void *e)
Definition: kern_trie.c:46
search_trieNode
struct Trie * search_trieNode(struct Trie *head, char *str)
Definition: kern_trie.c:70
Trie::e
void * e
Definition: kern_trie.h:39
Trie::isLeaf
u_int8_t isLeaf
Definition: kern_trie.h:37
kern_trie.h
kmalloc
void * kmalloc(uInt32 len)
Definition: kmalloc.c:241
Trie
Definition: kern_trie.h:36
CHAR_SIZE
#define CHAR_SIZE
Definition: kern_trie.h:34
kmalloc.h
new_trieNode
struct Trie * new_trieNode()
Definition: kern_trie.c:33
NULL
#define NULL
Definition: fat_string.h:17