N-sim
Emulation and simulation of
Wireless Sensor Networks



   Home


   Project Page


   Download


   CVS



   Installation


   Configuration


   Plug-ins




 Hosted by
SourceForge.net Logo

/home/brennan/n-sim/Vaike/linux/system-addons/networking/avl.c

Go to the documentation of this file.
00001 
00014 /*
00015  * Copyright 2007. Los Alamos National Security, LLC. This material
00016  * was produced under U.S. Government contract DE-AC52-06NA25396 for
00017  * Los Alamos National Laboratory (LANL), which is operated by Los
00018  * Alamos National Security, LLC, for the Department of Energy. The
00019  * U.S. Government has rights to use, reproduce, and distribute this
00020  * software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY,
00021  * LLC, MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LEGAL
00022  * LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified to
00023  * produce derivative works, such modified software should be clearly
00024  * marked, so as not to confuse it with the version available from LANL.
00025  *
00026  * Additionally, this program is free software; you can redistribute it
00027  * and/or modify it under the terms of the GNU General Public License as
00028  * published by the Free Software Foundation; either version 2 of the
00029  * License, or (at your option) any later version. Accordingly, this
00030  * program is distributed in the hope it will be useful, but WITHOUT ANY
00031  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
00032  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
00033  * for more details.
00034  */
00035 
00036 
00037 #ifdef __KERNEL__
00038 
00039 # include <linux/slab.h>
00040 # include <linux/errno.h>
00041 
00042 # define avl_malloc(size)   kmalloc(size, GFP_KERNEL)
00043 # define avl_free(ptr)      kfree(ptr)
00044 # define avl_error(...)     printk(KERN_ERR __VA_ARGS__)
00045 # define avl_log(...)       printk(KERN_INFO __VA_ARGS__)
00046 # define return_errno(num)  return (num < 0 ? num : (0 - num))
00047 
00048 #else
00049 
00050 # include <stdio.h>
00051 # include <stdlib.h>
00052 # include <errno.h>
00053 # include <syslog.h>
00054 
00055 # define avl_malloc(size)   malloc(size)
00056 # define avl_free(ptr)      free(ptr)
00057 # define avl_error(...)     syslog(LOG_ERR, __VA_ARGS__)
00058 # define avl_log(...)       syslog(LOG_INFO, __VA_ARGS__)
00059 # define return_errno(num)  do { errno = num; return -1; } while (0)
00060 
00061 #endif
00062 
00063 #include "avl.h"
00064 
00065 
00066 enum { LEFT = 0, RIGHT = 1 };
00067 
00068 
00069 static inline int maximum(int a, int b)
00070 {
00071         return a > b ? a :b;
00072 }
00073 
00074 static inline int height(struct avlnode *tree)
00075 {
00076         if (tree == NULL) {
00077                 return_errno(EINVAL);
00078         }
00079         return tree->height;
00080 }
00081 
00082 
00083 static struct avlnode *rotate(struct avlnode *node, int direction)
00084 {
00085         struct avlnode *child;
00086         if (node == NULL)
00087                 return NULL;
00088 
00089         if (direction == LEFT) {
00090                 child = node->right;
00091                 node->right = child->left;
00092                 child->left = node;
00093         } else {
00094                 child = node->left;
00095                 node->left = child->right;
00096                 child->right = node;
00097         }
00098 
00099         node->height = 1 + maximum(height(node->left), height(node->right));
00100         child->height = 1 + maximum(height(child->left), height(child->right));
00101 
00102         return child;
00103 }
00104 
00105 
00106 static struct avlnode *double_rotate(struct avlnode *node, int direction)
00107 {
00108         struct avlnode *child, *parent;
00109         if (node == NULL)
00110                 return NULL;
00111 
00112         if (direction == LEFT) {
00113                 child = node->right;
00114                 parent = child->left;
00115                 child->left = parent->right;
00116                 parent->right = child;
00117                 node->right = parent->left;
00118                 parent->left = node;
00119         } else {
00120                 child = node->left;
00121                 parent = child->right;
00122                 child->right = parent->left;
00123                 parent->left = child;
00124                 node->left = parent->right;
00125                 parent->right = node;
00126         }
00127         parent->height = 1 + maximum(height(parent->left), 
00128                                      height(parent->right));
00129         node->height = 1 + maximum(height(node->left), height(node->right));
00130         child->height = 1 + maximum(height(child->left), height(child->right));
00131 
00132         return parent;
00133 }
00134 
00135 
00136 
00137 
00138 
00139 unsigned long avl_size(struct avltree *tree)
00140 {
00141         unsigned long i = 0;
00142         struct avlnode *list;
00143 
00144         for (list = avl_find_min(tree); list != NULL; list = list->next)
00145                 i++;
00146 
00147         return i;
00148 }
00149 
00150 
00151 struct avlnode *avl_find(unsigned long key, struct avltree *tree)
00152 {
00153         int i = 0;
00154         struct avlnode *node;
00155 
00156         if (tree == NULL)
00157                 return NULL;
00158         node = tree->root;
00159 
00160         while (node != NULL) {
00161                 if (key == node->key)
00162                         break;
00163                 if (key < node->key)
00164                         node = node->left;
00165                 else if (key > node->key)
00166                         node = node->right;
00167                 i++;
00168         }
00169         return node;
00170 }
00171 
00172 
00173 void *avl_retrieve(unsigned long key, struct avltree *tree)
00174 {
00175         struct avlnode *node;
00176         if ((node = avl_find(key, tree)) == NULL)
00177                 return NULL;
00178         return node->element;
00179 }
00180 
00181 
00182 struct avlnode *avl_find_min(struct avltree *tree)
00183 {
00184         struct avlnode *node;
00185 
00186         if (tree == NULL)
00187                 return NULL;
00188 
00189         node = tree->root;
00190         if (node == NULL)
00191                 return NULL;
00192 
00193         while (node->left != NULL)
00194                 node = node->left;
00195 
00196         return node;
00197 }
00198 
00199 
00200 struct avlnode *avl_find_max(struct avltree *tree)
00201 {
00202         struct avlnode *node;
00203 
00204         if (tree == NULL)
00205                 return NULL;
00206 
00207         node = tree->root;
00208         if (node == NULL)
00209                 return NULL;
00210 
00211         while (node->right != NULL)
00212                 node = node->right;
00213 
00214         return node;
00215 }
00216 
00217 
00218 
00219 static struct avlnode *__avl_ins(void *elt, unsigned long key, 
00220                                  struct avlnode *tree, struct avlnode *parent, 
00221                                  int direction, int *error)
00222 {
00223         if (tree == NULL) {
00224                 tree = avl_malloc(sizeof(struct avlnode));
00225                 if (tree == NULL) {
00226                         *error = 1;
00227                         return NULL;
00228                 }
00229                 tree->key = key;
00230                 tree->element = elt;
00231                 tree->left = tree->right = NULL;
00232                 tree->next = tree->prev = NULL;
00233 
00234                 if (direction == LEFT) {
00235                         tree->next = parent;
00236                         tree->prev = parent->prev;
00237                         if (parent->prev != NULL)
00238                                 parent->prev->next = tree;
00239                         parent->prev = tree;
00240                 } else if (direction == RIGHT) {
00241                         tree->next = parent->next;
00242                         tree->prev = parent;
00243                         if (parent->next != NULL)
00244                                 parent->next->prev = tree;
00245                         parent->next = tree;
00246                 }
00247         } else if (key < tree->key) {
00248                 tree->left = __avl_ins(elt, key, tree->left, tree, 
00249                                        LEFT, error);
00250 
00251                 if (height(tree->left) - height(tree->right) >= 2) {
00252                         if (height(tree->left->left) - 
00253                             height(tree->left->right) >= 1)
00254                                 tree = rotate(tree, RIGHT);
00255                         else if (height(tree->left->right) - 
00256                                  height(tree->left->left) >= 1)
00257                                 tree = double_rotate(tree, RIGHT);
00258                 }
00259         } else if (key > tree->key) {
00260                 tree->right = __avl_ins(elt, key, tree->right, tree, 
00261                                         RIGHT, error);
00262 
00263                 if (height(tree->right) - height(tree->left) >= 2) {
00264                         if (height(tree->right->right) - 
00265                             height(tree->right->left) >= 1)
00266                                 tree = rotate(tree, LEFT);
00267                         else if (height(tree->right->left) - 
00268                                  height(tree->right->right) >= 1)
00269                                 tree = double_rotate(tree, LEFT);
00270                 }
00271         } else if (key == tree->key) {
00272                 *error = 1;
00273         }
00274 
00275         tree->height = 1 + maximum(height(tree->left), height(tree->right));
00276         return tree;
00277 }
00278 
00279 
00280 
00281 int avl_insert(void *elt, unsigned long key, struct avltree *tree)
00282 {
00283         int error = 0;
00284         if (tree == NULL || elt == NULL) {
00285                 return_errno(EINVAL);
00286         }
00287 
00288         tree->root = __avl_ins(elt, key, tree->root, NULL, -1, &error);
00289         return error;
00290 }
00291 
00292 
00293 
00294 static struct avlnode *__avl_del(void *elt, unsigned long key, 
00295                                  struct avlnode *tree, struct avlnode *parent,
00296                                  int direction, int *error)
00297 {
00298         if (tree == NULL) {
00299                 *error = 1;
00300                 return NULL;
00301         } else if (key == tree->key) {
00302                 if (tree->next != NULL)
00303                         tree->next->prev = tree->prev;
00304                 if (tree->prev != NULL)
00305                         tree->prev->next = tree->next;
00306                 if (direction == LEFT)
00307                         parent->left = NULL;
00308                 else if (direction == RIGHT)
00309                         parent->right = NULL;
00310                 avl_free(tree);
00311                 return NULL;
00312         } else if (key < tree->key) {
00313                 tree->left = __avl_del(elt, key, tree->right, tree, 
00314                                        LEFT, error);
00315 
00316                 if (height(tree->left) - height(tree->right) >= 2) {
00317                         if (height(tree->left->left) - 
00318                             height(tree->left->right) >= 1)
00319                                 tree = rotate(tree, RIGHT);
00320                         else if (height(tree->left->right) - 
00321                                  height(tree->left->left) >= 1)
00322                                 tree = double_rotate(tree, RIGHT);
00323                 }
00324         } else if (key > tree->key) {
00325                 tree->right = __avl_del(elt, key, tree->right, tree, 
00326                                         RIGHT, error);
00327 
00328                 if (height(tree->right) - height(tree->left) >= 2) {
00329                         if (height(tree->right->right) - 
00330                             height(tree->right->left) >= 1)
00331                                 tree = rotate(tree, LEFT);
00332                         else if (height(tree->right->left) - 
00333                                  height(tree->right->right) >= 1)
00334                                 tree = double_rotate(tree, LEFT);
00335                 }
00336         }
00337 
00338         tree->height = 1 + maximum(height(tree->left), height(tree->right));
00339         return tree;
00340 }
00341 
00342 
00343 int avl_delete(void *elt, unsigned long key, struct avltree *tree)
00344 {
00345         int error = 0;
00346         if (tree == NULL) {
00347                 return_errno(EINVAL);
00348         }
00349 
00350         tree->root = __avl_del(elt, key, tree->root, NULL, -1, &error);
00351         return error;
00352 }
00353 
00354 
00355 
00356 void destroy_avltree(struct avlnode *root)
00357 {
00358         if (root != NULL) {
00359                 destroy_avltree(root->left);
00360                 destroy_avltree(root->right);
00361                 avl_free(root);
00362         }
00363 }
00364 
00365 
00366 
00367 
00368 
00369 static void __avl_print(struct avlnode *tree, int direction, int indent)
00370 {
00371         int i;
00372         if (tree != NULL) {
00373                 __avl_print(tree->right, RIGHT, indent + 1);
00374 
00375                 for (i = 0; i < indent - 1; i++)
00376                         avl_log("    ");
00377                 if (indent) {
00378                         if (direction == LEFT)
00379                                 avl_log(" \\-- ");
00380                         else 
00381                                 avl_log(" /-- ");
00382                 }
00383                 avl_log("%ld\n", tree->key);
00384 
00385                 __avl_print(tree->left, LEFT, indent + 1);
00386         }
00387 }
00388 
00389 void avl_print(struct avltree *tree)
00390 {
00391         if (tree == NULL)
00392                 return;
00393 
00394         avl_log("AVL tree: \n");
00395         __avl_print(tree->root, -1, 0);
00396 }
00397 
00398 
00399 void avl_print_list(struct avltree *tree)
00400 {
00401         int i;
00402         struct avlnode *list = avl_find_min(tree);
00403 
00404         if (list == NULL)
00405                 return;
00406 
00407         avl_log("Linked list:  %ld ", list->key);
00408         for (i = 1, list = list->next; list != NULL; list = list->next, i++)
00409                 avl_log("-> %ld ", list->key);
00410         avl_log("\n\n");
00411 }


© 2007, Los Alamos National Security, LLC.