Return to radix.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc |
1.1 ! misho 1: /* ! 2: * Copyright (C) 2007-2009 Internet Systems Consortium, Inc. ("ISC") ! 3: * ! 4: * Permission to use, copy, modify, and/or distribute this software for any ! 5: * purpose with or without fee is hereby granted, provided that the above ! 6: * copyright notice and this permission notice appear in all copies. ! 7: * ! 8: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ! 9: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ! 10: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ! 11: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 12: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ! 13: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ! 14: * PERFORMANCE OF THIS SOFTWARE. ! 15: */ ! 16: ! 17: /* $Id: radix.c,v 1.20.36.3 2009/01/18 23:47:41 tbox Exp $ */ ! 18: ! 19: /* ! 20: * This source was adapted from MRT's RCS Ids: ! 21: * Id: radix.c,v 1.10.2.1 1999/11/29 05:16:24 masaki Exp ! 22: * Id: prefix.c,v 1.37.2.9 2000/03/10 02:53:19 labovit Exp ! 23: */ ! 24: ! 25: #include <config.h> ! 26: ! 27: #include <isc/mem.h> ! 28: #include <isc/types.h> ! 29: #include <isc/util.h> ! 30: #include <isc/radix.h> ! 31: ! 32: static isc_result_t ! 33: _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, ! 34: void *dest, int bitlen); ! 35: ! 36: static void ! 37: _deref_prefix(isc_mem_t *mctx, isc_prefix_t *prefix); ! 38: ! 39: static isc_result_t ! 40: _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix); ! 41: ! 42: static int ! 43: _comp_with_mask(void *addr, void *dest, u_int mask); ! 44: ! 45: static void ! 46: _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func); ! 47: ! 48: static isc_result_t ! 49: _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest, ! 50: int bitlen) ! 51: { ! 52: isc_prefix_t *prefix; ! 53: ! 54: REQUIRE(target != NULL); ! 55: ! 56: if (family != AF_INET6 && family != AF_INET && family != AF_UNSPEC) ! 57: return (ISC_R_NOTIMPLEMENTED); ! 58: ! 59: prefix = isc_mem_get(mctx, sizeof(isc_prefix_t)); ! 60: if (prefix == NULL) ! 61: return (ISC_R_NOMEMORY); ! 62: ! 63: if (family == AF_INET6) { ! 64: prefix->bitlen = (bitlen >= 0) ? bitlen : 128; ! 65: memcpy(&prefix->add.sin6, dest, 16); ! 66: } else { ! 67: /* AF_UNSPEC is "any" or "none"--treat it as AF_INET */ ! 68: prefix->bitlen = (bitlen >= 0) ? bitlen : 32; ! 69: memcpy(&prefix->add.sin, dest, 4); ! 70: } ! 71: ! 72: prefix->family = family; ! 73: ! 74: isc_refcount_init(&prefix->refcount, 1); ! 75: ! 76: *target = prefix; ! 77: return (ISC_R_SUCCESS); ! 78: } ! 79: ! 80: static void ! 81: _deref_prefix(isc_mem_t *mctx, isc_prefix_t *prefix) { ! 82: int refs; ! 83: ! 84: if (prefix == NULL) ! 85: return; ! 86: ! 87: isc_refcount_decrement(&prefix->refcount, &refs); ! 88: ! 89: if (refs <= 0) { ! 90: isc_refcount_destroy(&prefix->refcount); ! 91: isc_mem_put(mctx, prefix, sizeof(isc_prefix_t)); ! 92: } ! 93: } ! 94: ! 95: static isc_result_t ! 96: _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) { ! 97: INSIST(prefix != NULL); ! 98: INSIST((prefix->family == AF_INET && prefix->bitlen <= 32) || ! 99: (prefix->family == AF_INET6 && prefix->bitlen <= 128) || ! 100: (prefix->family == AF_UNSPEC && prefix->bitlen == 0)); ! 101: REQUIRE(target != NULL && *target == NULL); ! 102: ! 103: /* ! 104: * If this prefix is a static allocation, copy it into new memory. ! 105: * (Note, the refcount still has to be destroyed by the calling ! 106: * routine.) ! 107: */ ! 108: if (isc_refcount_current(&prefix->refcount) == 0) { ! 109: isc_result_t ret; ! 110: ret = _new_prefix(mctx, target, prefix->family, ! 111: &prefix->add, prefix->bitlen); ! 112: return ret; ! 113: } ! 114: ! 115: isc_refcount_increment(&prefix->refcount, NULL); ! 116: ! 117: *target = prefix; ! 118: return (ISC_R_SUCCESS); ! 119: } ! 120: ! 121: static int ! 122: _comp_with_mask(void *addr, void *dest, u_int mask) { ! 123: ! 124: /* Mask length of zero matches everything */ ! 125: if (mask == 0) ! 126: return (1); ! 127: ! 128: if (memcmp(addr, dest, mask / 8) == 0) { ! 129: int n = mask / 8; ! 130: int m = ((~0) << (8 - (mask % 8))); ! 131: ! 132: if ((mask % 8) == 0 || ! 133: (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m)) ! 134: return (1); ! 135: } ! 136: return (0); ! 137: } ! 138: ! 139: isc_result_t ! 140: isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) { ! 141: isc_radix_tree_t *radix; ! 142: ! 143: REQUIRE(target != NULL && *target == NULL); ! 144: ! 145: radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t)); ! 146: if (radix == NULL) ! 147: return (ISC_R_NOMEMORY); ! 148: ! 149: radix->mctx = mctx; ! 150: radix->maxbits = maxbits; ! 151: radix->head = NULL; ! 152: radix->num_active_node = 0; ! 153: radix->num_added_node = 0; ! 154: RUNTIME_CHECK(maxbits <= RADIX_MAXBITS); /* XXX */ ! 155: radix->magic = RADIX_TREE_MAGIC; ! 156: *target = radix; ! 157: return (ISC_R_SUCCESS); ! 158: } ! 159: ! 160: /* ! 161: * if func is supplied, it will be called as func(node->data) ! 162: * before deleting the node ! 163: */ ! 164: ! 165: static void ! 166: _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) { ! 167: ! 168: REQUIRE(radix != NULL); ! 169: ! 170: if (radix->head != NULL) { ! 171: ! 172: isc_radix_node_t *Xstack[RADIX_MAXBITS+1]; ! 173: isc_radix_node_t **Xsp = Xstack; ! 174: isc_radix_node_t *Xrn = radix->head; ! 175: ! 176: while (Xrn != NULL) { ! 177: isc_radix_node_t *l = Xrn->l; ! 178: isc_radix_node_t *r = Xrn->r; ! 179: ! 180: if (Xrn->prefix != NULL) { ! 181: _deref_prefix(radix->mctx, Xrn->prefix); ! 182: if (func != NULL && (Xrn->data[0] != NULL || ! 183: Xrn->data[1] != NULL)) ! 184: func(Xrn->data); ! 185: } else { ! 186: INSIST(Xrn->data[0] == NULL && ! 187: Xrn->data[1] == NULL); ! 188: } ! 189: ! 190: isc_mem_put(radix->mctx, Xrn, sizeof(*Xrn)); ! 191: radix->num_active_node--; ! 192: ! 193: if (l != NULL) { ! 194: if (r != NULL) { ! 195: *Xsp++ = r; ! 196: } ! 197: Xrn = l; ! 198: } else if (r != NULL) { ! 199: Xrn = r; ! 200: } else if (Xsp != Xstack) { ! 201: Xrn = *(--Xsp); ! 202: } else { ! 203: Xrn = NULL; ! 204: } ! 205: } ! 206: } ! 207: RUNTIME_CHECK(radix->num_active_node == 0); ! 208: } ! 209: ! 210: ! 211: void ! 212: isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) ! 213: { ! 214: REQUIRE(radix != NULL); ! 215: _clear_radix(radix, func); ! 216: isc_mem_put(radix->mctx, radix, sizeof(*radix)); ! 217: } ! 218: ! 219: ! 220: /* ! 221: * func will be called as func(node->prefix, node->data) ! 222: */ ! 223: void ! 224: isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) ! 225: { ! 226: isc_radix_node_t *node; ! 227: ! 228: REQUIRE(func != NULL); ! 229: ! 230: RADIX_WALK(radix->head, node) { ! 231: func(node->prefix, node->data); ! 232: } RADIX_WALK_END; ! 233: } ! 234: ! 235: ! 236: isc_result_t ! 237: isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target, ! 238: isc_prefix_t *prefix) ! 239: { ! 240: isc_radix_node_t *node; ! 241: isc_radix_node_t *stack[RADIX_MAXBITS + 1]; ! 242: u_char *addr; ! 243: isc_uint32_t bitlen; ! 244: int tfamily = -1; ! 245: int cnt = 0; ! 246: ! 247: REQUIRE(radix != NULL); ! 248: REQUIRE(prefix != NULL); ! 249: REQUIRE(target != NULL && *target == NULL); ! 250: RUNTIME_CHECK(prefix->bitlen <= radix->maxbits); ! 251: ! 252: *target = NULL; ! 253: ! 254: if (radix->head == NULL) { ! 255: return (ISC_R_NOTFOUND); ! 256: } ! 257: ! 258: node = radix->head; ! 259: addr = isc_prefix_touchar(prefix); ! 260: bitlen = prefix->bitlen; ! 261: ! 262: while (node->bit < bitlen) { ! 263: if (node->prefix) ! 264: stack[cnt++] = node; ! 265: ! 266: if (BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) ! 267: node = node->r; ! 268: else ! 269: node = node->l; ! 270: ! 271: if (node == NULL) ! 272: break; ! 273: } ! 274: ! 275: if (node && node->prefix) ! 276: stack[cnt++] = node; ! 277: ! 278: while (--cnt >= 0) { ! 279: node = stack[cnt]; ! 280: ! 281: if (_comp_with_mask(isc_prefix_tochar(node->prefix), ! 282: isc_prefix_tochar(prefix), ! 283: node->prefix->bitlen)) { ! 284: if (node->node_num[ISC_IS6(prefix->family)] != -1 && ! 285: ((*target == NULL) || ! 286: (*target)->node_num[ISC_IS6(tfamily)] > ! 287: node->node_num[ISC_IS6(prefix->family)])) { ! 288: *target = node; ! 289: tfamily = prefix->family; ! 290: } ! 291: } ! 292: } ! 293: ! 294: if (*target == NULL) { ! 295: return (ISC_R_NOTFOUND); ! 296: } else { ! 297: return (ISC_R_SUCCESS); ! 298: } ! 299: } ! 300: ! 301: isc_result_t ! 302: isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target, ! 303: isc_radix_node_t *source, isc_prefix_t *prefix) ! 304: { ! 305: isc_radix_node_t *node, *new_node, *parent, *glue = NULL; ! 306: u_char *addr, *test_addr; ! 307: isc_uint32_t bitlen, fam, check_bit, differ_bit; ! 308: isc_uint32_t i, j, r; ! 309: isc_result_t result; ! 310: ! 311: REQUIRE(radix != NULL); ! 312: REQUIRE(target != NULL && *target == NULL); ! 313: REQUIRE(prefix != NULL || (source != NULL && source->prefix != NULL)); ! 314: RUNTIME_CHECK(prefix == NULL || prefix->bitlen <= radix->maxbits); ! 315: ! 316: if (prefix == NULL) ! 317: prefix = source->prefix; ! 318: ! 319: INSIST(prefix != NULL); ! 320: ! 321: bitlen = prefix->bitlen; ! 322: fam = prefix->family; ! 323: ! 324: if (radix->head == NULL) { ! 325: node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); ! 326: if (node == NULL) ! 327: return (ISC_R_NOMEMORY); ! 328: node->bit = bitlen; ! 329: node->node_num[0] = node->node_num[1] = -1; ! 330: node->prefix = NULL; ! 331: result = _ref_prefix(radix->mctx, &node->prefix, prefix); ! 332: if (result != ISC_R_SUCCESS) { ! 333: isc_mem_put(radix->mctx, node, ! 334: sizeof(isc_radix_node_t)); ! 335: return (result); ! 336: } ! 337: node->parent = NULL; ! 338: node->l = node->r = NULL; ! 339: if (source != NULL) { ! 340: /* ! 341: * If source is non-NULL, then we're merging in a ! 342: * node from an existing radix tree. To keep ! 343: * the node_num values consistent, the calling ! 344: * function will add the total number of nodes ! 345: * added to num_added_node at the end of ! 346: * the merge operation--we don't do it here. ! 347: */ ! 348: if (source->node_num[0] != -1) ! 349: node->node_num[0] = radix->num_added_node + ! 350: source->node_num[0]; ! 351: if (source->node_num[1] != -1) ! 352: node->node_num[1] = radix->num_added_node + ! 353: source->node_num[1]; ! 354: node->data[0] = source->data[0]; ! 355: node->data[1] = source->data[1]; ! 356: } else { ! 357: if (fam == AF_UNSPEC) { ! 358: /* "any" or "none" */ ! 359: node->node_num[0] = node->node_num[1] = ! 360: ++radix->num_added_node; ! 361: } else { ! 362: node->node_num[ISC_IS6(fam)] = ! 363: ++radix->num_added_node; ! 364: } ! 365: node->data[0] = NULL; ! 366: node->data[1] = NULL; ! 367: } ! 368: radix->head = node; ! 369: radix->num_active_node++; ! 370: *target = node; ! 371: return (ISC_R_SUCCESS); ! 372: } ! 373: ! 374: addr = isc_prefix_touchar(prefix); ! 375: node = radix->head; ! 376: ! 377: while (node->bit < bitlen || node->prefix == NULL) { ! 378: if (node->bit < radix->maxbits && ! 379: BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) ! 380: { ! 381: if (node->r == NULL) ! 382: break; ! 383: node = node->r; ! 384: } else { ! 385: if (node->l == NULL) ! 386: break; ! 387: node = node->l; ! 388: } ! 389: ! 390: INSIST(node != NULL); ! 391: } ! 392: ! 393: INSIST(node->prefix != NULL); ! 394: ! 395: test_addr = isc_prefix_touchar(node->prefix); ! 396: /* Find the first bit different. */ ! 397: check_bit = (node->bit < bitlen) ? node->bit : bitlen; ! 398: differ_bit = 0; ! 399: for (i = 0; i*8 < check_bit; i++) { ! 400: if ((r = (addr[i] ^ test_addr[i])) == 0) { ! 401: differ_bit = (i + 1) * 8; ! 402: continue; ! 403: } ! 404: /* I know the better way, but for now. */ ! 405: for (j = 0; j < 8; j++) { ! 406: if (BIT_TEST (r, (0x80 >> j))) ! 407: break; ! 408: } ! 409: /* Must be found. */ ! 410: INSIST(j < 8); ! 411: differ_bit = i * 8 + j; ! 412: break; ! 413: } ! 414: ! 415: if (differ_bit > check_bit) ! 416: differ_bit = check_bit; ! 417: ! 418: parent = node->parent; ! 419: while (parent != NULL && parent->bit >= differ_bit) { ! 420: node = parent; ! 421: parent = node->parent; ! 422: } ! 423: ! 424: if (differ_bit == bitlen && node->bit == bitlen) { ! 425: if (node->prefix != NULL) { ! 426: /* Set node_num only if it hasn't been set before */ ! 427: if (source != NULL) { ! 428: /* Merging node */ ! 429: if (node->node_num[0] == -1 && ! 430: source->node_num[0] != -1) { ! 431: node->node_num[0] = ! 432: radix->num_added_node + ! 433: source->node_num[0]; ! 434: node->data[0] = source->data[0]; ! 435: } ! 436: if (node->node_num[1] == -1 && ! 437: source->node_num[0] != -1) { ! 438: node->node_num[1] = ! 439: radix->num_added_node + ! 440: source->node_num[1]; ! 441: node->data[1] = source->data[1]; ! 442: } ! 443: } else { ! 444: if (fam == AF_UNSPEC) { ! 445: /* "any" or "none" */ ! 446: int next = radix->num_added_node + 1; ! 447: if (node->node_num[0] == -1) { ! 448: node->node_num[0] = next; ! 449: radix->num_added_node = next; ! 450: } ! 451: if (node->node_num[1] == -1) { ! 452: node->node_num[1] = next; ! 453: radix->num_added_node = next; ! 454: } ! 455: } else { ! 456: if (node->node_num[ISC_IS6(fam)] == -1) ! 457: node->node_num[ISC_IS6(fam)] ! 458: = ++radix->num_added_node; ! 459: } ! 460: } ! 461: *target = node; ! 462: return (ISC_R_SUCCESS); ! 463: } else { ! 464: result = ! 465: _ref_prefix(radix->mctx, &node->prefix, prefix); ! 466: if (result != ISC_R_SUCCESS) ! 467: return (result); ! 468: } ! 469: INSIST(node->data[0] == NULL && node->node_num[0] == -1 && ! 470: node->data[1] == NULL && node->node_num[1] == -1); ! 471: if (source != NULL) { ! 472: /* Merging node */ ! 473: if (source->node_num[0] != -1) { ! 474: node->node_num[0] = radix->num_added_node + ! 475: source->node_num[0]; ! 476: node->data[0] = source->data[0]; ! 477: } ! 478: if (source->node_num[1] != -1) { ! 479: node->node_num[1] = radix->num_added_node + ! 480: source->node_num[1]; ! 481: node->data[1] = source->data[1]; ! 482: } ! 483: } else { ! 484: if (fam == AF_UNSPEC) { ! 485: /* "any" or "none" */ ! 486: node->node_num[0] = node->node_num[1] = ! 487: ++radix->num_added_node; ! 488: } else { ! 489: node->node_num[ISC_IS6(fam)] = ! 490: ++radix->num_added_node; ! 491: } ! 492: } ! 493: *target = node; ! 494: return (ISC_R_SUCCESS); ! 495: } ! 496: ! 497: new_node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); ! 498: if (new_node == NULL) ! 499: return (ISC_R_NOMEMORY); ! 500: if (node->bit != differ_bit && bitlen != differ_bit) { ! 501: glue = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t)); ! 502: if (glue == NULL) { ! 503: isc_mem_put(radix->mctx, new_node, ! 504: sizeof(isc_radix_node_t)); ! 505: return (ISC_R_NOMEMORY); ! 506: } ! 507: } ! 508: new_node->bit = bitlen; ! 509: new_node->prefix = NULL; ! 510: result = _ref_prefix(radix->mctx, &new_node->prefix, prefix); ! 511: if (result != ISC_R_SUCCESS) { ! 512: isc_mem_put(radix->mctx, new_node, sizeof(isc_radix_node_t)); ! 513: if (glue != NULL) ! 514: isc_mem_put(radix->mctx, glue, ! 515: sizeof(isc_radix_node_t)); ! 516: return (result); ! 517: } ! 518: new_node->parent = NULL; ! 519: new_node->l = new_node->r = NULL; ! 520: new_node->node_num[0] = new_node->node_num[1] = -1; ! 521: radix->num_active_node++; ! 522: ! 523: if (source != NULL) { ! 524: /* Merging node */ ! 525: if (source->node_num[0] != -1) ! 526: new_node->node_num[0] = radix->num_added_node + ! 527: source->node_num[0]; ! 528: if (source->node_num[1] != -1) ! 529: new_node->node_num[1] = radix->num_added_node + ! 530: source->node_num[1]; ! 531: new_node->data[0] = source->data[0]; ! 532: new_node->data[1] = source->data[1]; ! 533: } else { ! 534: if (fam == AF_UNSPEC) { ! 535: /* "any" or "none" */ ! 536: new_node->node_num[0] = new_node->node_num[1] = ! 537: ++radix->num_added_node; ! 538: } else { ! 539: new_node->node_num[ISC_IS6(fam)] = ! 540: ++radix->num_added_node; ! 541: } ! 542: new_node->data[0] = NULL; ! 543: new_node->data[1] = NULL; ! 544: } ! 545: ! 546: if (node->bit == differ_bit) { ! 547: INSIST(glue == NULL); ! 548: new_node->parent = node; ! 549: if (node->bit < radix->maxbits && ! 550: BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07))) ! 551: { ! 552: INSIST(node->r == NULL); ! 553: node->r = new_node; ! 554: } else { ! 555: INSIST(node->l == NULL); ! 556: node->l = new_node; ! 557: } ! 558: *target = new_node; ! 559: return (ISC_R_SUCCESS); ! 560: } ! 561: ! 562: if (bitlen == differ_bit) { ! 563: INSIST(glue == NULL); ! 564: if (bitlen < radix->maxbits && ! 565: BIT_TEST(test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) { ! 566: new_node->r = node; ! 567: } else { ! 568: new_node->l = node; ! 569: } ! 570: new_node->parent = node->parent; ! 571: if (node->parent == NULL) { ! 572: INSIST(radix->head == node); ! 573: radix->head = new_node; ! 574: } else if (node->parent->r == node) { ! 575: node->parent->r = new_node; ! 576: } else { ! 577: node->parent->l = new_node; ! 578: } ! 579: node->parent = new_node; ! 580: } else { ! 581: INSIST(glue != NULL); ! 582: glue->bit = differ_bit; ! 583: glue->prefix = NULL; ! 584: glue->parent = node->parent; ! 585: glue->data[0] = glue->data[1] = NULL; ! 586: glue->node_num[0] = glue->node_num[1] = -1; ! 587: radix->num_active_node++; ! 588: if (differ_bit < radix->maxbits && ! 589: BIT_TEST(addr[differ_bit>>3], 0x80 >> (differ_bit & 07))) { ! 590: glue->r = new_node; ! 591: glue->l = node; ! 592: } else { ! 593: glue->r = node; ! 594: glue->l = new_node; ! 595: } ! 596: new_node->parent = glue; ! 597: ! 598: if (node->parent == NULL) { ! 599: INSIST(radix->head == node); ! 600: radix->head = glue; ! 601: } else if (node->parent->r == node) { ! 602: node->parent->r = glue; ! 603: } else { ! 604: node->parent->l = glue; ! 605: } ! 606: node->parent = glue; ! 607: } ! 608: ! 609: *target = new_node; ! 610: return (ISC_R_SUCCESS); ! 611: } ! 612: ! 613: void ! 614: isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) { ! 615: isc_radix_node_t *parent, *child; ! 616: ! 617: REQUIRE(radix != NULL); ! 618: REQUIRE(node != NULL); ! 619: ! 620: if (node->r && node->l) { ! 621: /* ! 622: * This might be a placeholder node -- have to check and ! 623: * make sure there is a prefix associated with it! ! 624: */ ! 625: if (node->prefix != NULL) ! 626: _deref_prefix(radix->mctx, node->prefix); ! 627: ! 628: node->prefix = NULL; ! 629: node->data[0] = node->data[1] = NULL; ! 630: return; ! 631: } ! 632: ! 633: if (node->r == NULL && node->l == NULL) { ! 634: parent = node->parent; ! 635: _deref_prefix(radix->mctx, node->prefix); ! 636: isc_mem_put(radix->mctx, node, sizeof(*node)); ! 637: radix->num_active_node--; ! 638: ! 639: if (parent == NULL) { ! 640: INSIST(radix->head == node); ! 641: radix->head = NULL; ! 642: return; ! 643: } ! 644: ! 645: if (parent->r == node) { ! 646: parent->r = NULL; ! 647: child = parent->l; ! 648: } else { ! 649: INSIST(parent->l == node); ! 650: parent->l = NULL; ! 651: child = parent->r; ! 652: } ! 653: ! 654: if (parent->prefix) ! 655: return; ! 656: ! 657: /* We need to remove parent too. */ ! 658: ! 659: if (parent->parent == NULL) { ! 660: INSIST(radix->head == parent); ! 661: radix->head = child; ! 662: } else if (parent->parent->r == parent) { ! 663: parent->parent->r = child; ! 664: } else { ! 665: INSIST(parent->parent->l == parent); ! 666: parent->parent->l = child; ! 667: } ! 668: child->parent = parent->parent; ! 669: isc_mem_put(radix->mctx, parent, sizeof(*parent)); ! 670: radix->num_active_node--; ! 671: return; ! 672: } ! 673: ! 674: if (node->r) { ! 675: child = node->r; ! 676: } else { ! 677: INSIST(node->l != NULL); ! 678: child = node->l; ! 679: } ! 680: parent = node->parent; ! 681: child->parent = parent; ! 682: ! 683: _deref_prefix(radix->mctx, node->prefix); ! 684: isc_mem_put(radix->mctx, node, sizeof(*node)); ! 685: radix->num_active_node--; ! 686: ! 687: if (parent == NULL) { ! 688: INSIST(radix->head == node); ! 689: radix->head = child; ! 690: return; ! 691: } ! 692: ! 693: if (parent->r == node) { ! 694: parent->r = child; ! 695: } else { ! 696: INSIST(parent->l == node); ! 697: parent->l = child; ! 698: } ! 699: } ! 700: ! 701: /* ! 702: Local Variables: ! 703: c-basic-offset: 4 ! 704: indent-tabs-mode: t ! 705: End: ! 706: */