char name[1];
} DICT_VENDOR;
+typedef union value_pair_data {
+ char strvalue[MAX_STRING_LEN];
+ uint8_t octets[MAX_STRING_LEN];
+ struct in_addr ipaddr;
+ struct in6_addr ipv6addr;
+ uint32_t date;
+ uint32_t integer;
+ uint8_t filter[32];
+ uint8_t ifid[8]; /* struct? */
+ uint8_t ipv6prefix[18]; /* struct? */
+} VALUE_PAIR_DATA;
+
typedef struct value_pair {
char name[40];
int attribute;
uint32_t lvalue; /* DELETE ME ASAP */
ATTR_FLAGS flags;
struct value_pair *next;
- union {
- char strvalue[MAX_STRING_LEN];
- uint8_t octets[MAX_STRING_LEN];
- struct in_addr ipaddr;
- struct in6_addr ipv6addr;
- uint32_t date;
- uint32_t integer;
- uint8_t filter[32];
- uint8_t ifid[8]; /* struct? */
- uint8_t ipv6prefix[18]; /* struct? */
- } data;
+ VALUE_PAIR_DATA data;
} VALUE_PAIR;
#define vp_strvalue data.strvalue
#define vp_octets data.octets
int replace_flag);
void rbtree_free(rbtree_t *tree);
int rbtree_insert(rbtree_t *tree, void *Data);
+rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data);
void rbtree_delete(rbtree_t *tree, rbnode_t *Z);
int rbtree_deletebydata(rbtree_t *tree, const void *data);
rbnode_t *rbtree_find(rbtree_t *tree, const void *Data);
void *ctx;
struct timeval when;
lrad_event_t **ev_p;
+ rbnode_t *node;
};
ev = *ev_p;
*(ev->ev_p) = NULL;
- rbtree_deletebydata(el->times, ev);
+ rbtree_delete(el->times, ev->node);
return 1;
}
* increase the usec counter by 1, in order to avoid the
* duplicate. If we can't insert it after 10 tries, die.
*/
- if (!rbtree_insert(el->times, ev)) {
+ ev->node = rbtree_insertnode(el->times, ev);
+ if (!ev->node) {
if (rbtree_finddata(el->times, ev)) {
int i;
continue;
}
- if (!rbtree_insert(el->times, ev)) {
+ ev->node = rbtree_insertnode(el->times, ev);
+ if (!ev->node) { /* error */
break;
}
/*
* Insert an element into the tree.
*/
-int rbtree_insert(rbtree_t *tree, void *Data)
+rbnode_t *rbtree_insertnode(rbtree_t *tree, void *Data)
{
rbnode_t *Current, *Parent, *X;
* Don't replace the entry.
*/
if (tree->replace_flag == 0) {
- return 0;
+ return NULL;
}
/*
*/
if (tree->freeNode) tree->freeNode(Current->Data);
Current->Data = Data;
- return 1;
+ return Current;
}
Parent = Current;
tree->num_elements++;
- return 1;
+ return X;
+}
+
+int rbtree_insert(rbtree_t *tree, void *Data)
+{
+ if (rbtree_insertnode(tree, Data)) return 1;
+ return 0;
}
static void DeleteFixup(rbtree_t *tree, rbnode_t *X, rbnode_t *Parent)
*/
void rbtree_delete(rbtree_t *tree, rbnode_t *Z)
{
+ int fixup = 0;
rbnode_t *X, *Y;
rbnode_t *Parent;
tree->Root = X;
if (Y != Z) {
- /*
- * Move the child's data to here, and then
- * re-balance the tree.
- */
if (tree->freeNode) tree->freeNode(Z->Data);
Z->Data = Y->Data;
Y->Data = NULL;
- } else if (tree->freeNode) {
- tree->freeNode(Z->Data);
- }
- if (Y->Color == Black && X != NIL)
- DeleteFixup(tree, X, Parent);
+ if (Y->Color == Black && X != NIL)
+ DeleteFixup(tree, X, Parent);
+
+ /*
+ * The user structure in Y->Data MAY include a
+ * pointer to Y. In that case, we CANNOT delete
+ * Y. Instead, we copy Z (which is now in the
+ * tree) to Y, and fix up the parent/child
+ * pointers.
+ */
+ memcpy(Y, Z, sizeof(*Y));
+
+ if (!Y->Parent) {
+ tree->Root = Y;
+ } else {
+ if (Y->Parent->Left == Z) Y->Parent->Left = Y;
+ if (Y->Parent->Right == Z) Y->Parent->Right = Y;
+ }
+ if (Y->Left->Parent == Z) Y->Left->Parent = Y;
+ if (Y->Right->Parent == Z) Y->Right->Parent = Y;
+
+ free(Z);
- free(Y);
+ } else {
+ if (tree->freeNode) tree->freeNode(Y->Data);
+
+ if (Y->Color == Black && X != NIL)
+ DeleteFixup(tree, X, Parent);
+
+ free(Y);
+ }
tree->num_elements--;
}