/*********************** -*- Mode: C -*- *********************** * File : bintree_insert.c *--------------------------------------------------------------- * Description * =========== * This operation adds a client node to the specified tree. * * tree - the "tree" instance to invoke this operation upon * clientnode - a pointer to a client node. NB the tree can find the * necessary util_BintreeNodeT from it's stored offset. * * RETURNS * 0 if the "clientnode" is added correctly to the tree. * * If another "clientnode" already exists in the tree with the same key, then * -1 is returned, and the tree remains unchanged. * * If the "clientnode" had not been initialised, then an assert will fire. * * If the bintree "node" is already part of a tree, then an assert will fire. * *--------------------------------------------------------------- * Author : Graeme McKerrell * Created On : Wed Jan 28 10:05:11 2004 * Status : TESTED *--------------------------------------------------------------- * HISTORY * 7-Dec-2004 Graeme McKerrell * Renamed to the "lub_" namespace * 5-May-2004 Graeme McKerrell * updates following review * 2-Mar-2004 Graeme McKerrell * fixed so that the insertion order is correct * 9-Feb-2004 Graeme McKerrell * updated to use the new getkey prototype and new node, key ordering * 28-Jan-2004 Graeme McKerrell * Initial version *--------------------------------------------------------------- * Copyright (C) 2004 3Com Corporation. All Rights Reserved. **************************************************************** */ #include #include "private.h" /*--------------------------------------------------------- */ int lub_bintree_insert(lub_bintree_t * this, void *clientnode) { int result = -1; lub_bintree_node_t *new; lub_bintree_key_t key; assert(clientnode); if (NULL != clientnode) { /* obtain the control block from the clientnode */ new = lub_bintree_getnode(this, clientnode); /* check this node is not currently in another tree */ assert(new->left == NULL); assert(new->right == NULL); /* add this node to the splay tree */ /* Insert "node" into the tree , unless it's already there. */ if (NULL == this->root) { this->root = new; this->root->left = this->root->right = NULL; result = 0; } else { int comp; /* get a key from the node */ this->getkeyFn(clientnode, &key); /* do the biz */ this->root = lub_bintree_splay(this, this->root, &key); /* * compare the new key with the detail found * in the tree */ comp = lub_bintree_compare(this, this->root, &key); if (comp > 0) { new->left = this->root->left; new->right = this->root; this->root->left = NULL; result = 0; } else if (comp < 0) { new->right = this->root->right; new->left = this->root; this->root->right = NULL; result = 0; } else { /* We get here if it's already in the tree */ } } if (0 == result) { /* update the tree root */ this->root = new; } } /* added OK */ return result; } /*--------------------------------------------------------- */