radix.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2007-2009, 2011-2014  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id$ */
00018 
00019 /*
00020  * This source was adapted from MRT's RCS Ids:
00021  * Id: radix.c,v 1.10.2.1 1999/11/29 05:16:24 masaki Exp
00022  * Id: prefix.c,v 1.37.2.9 2000/03/10 02:53:19 labovit Exp
00023  */
00024 
00025 #include <config.h>
00026 
00027 #include <isc/mem.h>
00028 #include <isc/types.h>
00029 #include <isc/util.h>
00030 #include <isc/radix.h>
00031 
00032 static isc_result_t
00033 _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family,
00034             void *dest, int bitlen);
00035 
00036 static void
00037 _deref_prefix(isc_prefix_t *prefix);
00038 
00039 static isc_result_t
00040 _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix);
00041 
00042 static int
00043 _comp_with_mask(void *addr, void *dest, u_int mask);
00044 
00045 static void
00046 _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func);
00047 
00048 static isc_result_t
00049 _new_prefix(isc_mem_t *mctx, isc_prefix_t **target, int family, void *dest,
00050             int bitlen)
00051 {
00052         isc_prefix_t *prefix;
00053 
00054         REQUIRE(target != NULL);
00055 
00056         if (family != AF_INET6 && family != AF_INET && family != AF_UNSPEC)
00057                 return (ISC_R_NOTIMPLEMENTED);
00058 
00059         prefix = isc_mem_get(mctx, sizeof(isc_prefix_t));
00060         if (prefix == NULL)
00061                 return (ISC_R_NOMEMORY);
00062 
00063         if (family == AF_INET6) {
00064                 prefix->bitlen = (bitlen >= 0) ? bitlen : 128;
00065                 memmove(&prefix->add.sin6, dest, 16);
00066         } else {
00067                 /* AF_UNSPEC is "any" or "none"--treat it as AF_INET */
00068                 prefix->bitlen = (bitlen >= 0) ? bitlen : 32;
00069                 memmove(&prefix->add.sin, dest, 4);
00070         }
00071 
00072         prefix->family = family;
00073         prefix->ecs = ISC_FALSE;
00074         prefix->mctx = NULL;
00075         isc_mem_attach(mctx, &prefix->mctx);
00076 
00077         isc_refcount_init(&prefix->refcount, 1);
00078 
00079         *target = prefix;
00080         return (ISC_R_SUCCESS);
00081 }
00082 
00083 static void
00084 _deref_prefix(isc_prefix_t *prefix) {
00085         int refs;
00086 
00087         if (prefix == NULL)
00088                 return;
00089 
00090         isc_refcount_decrement(&prefix->refcount, &refs);
00091 
00092         if (refs <= 0) {
00093                 isc_refcount_destroy(&prefix->refcount);
00094                 isc_mem_putanddetach(&prefix->mctx, prefix,
00095                                      sizeof(isc_prefix_t));
00096         }
00097 }
00098 
00099 static isc_result_t
00100 _ref_prefix(isc_mem_t *mctx, isc_prefix_t **target, isc_prefix_t *prefix) {
00101         INSIST(prefix != NULL);
00102         INSIST((prefix->family == AF_INET && prefix->bitlen <= 32) ||
00103                (prefix->family == AF_INET6 && prefix->bitlen <= 128) ||
00104                (prefix->family == AF_UNSPEC && prefix->bitlen == 0));
00105         REQUIRE(target != NULL && *target == NULL);
00106 
00107         /*
00108          * If this prefix is a static allocation, copy it into new memory.
00109          * (Note, the refcount still has to be destroyed by the calling
00110          * routine.)
00111          */
00112         if (isc_refcount_current(&prefix->refcount) == 0) {
00113                 isc_result_t ret;
00114                 ret = _new_prefix(mctx, target, prefix->family,
00115                                   &prefix->add, prefix->bitlen);
00116                 return (ret);
00117         }
00118 
00119         isc_refcount_increment(&prefix->refcount, NULL);
00120 
00121         *target = prefix;
00122         return (ISC_R_SUCCESS);
00123 }
00124 
00125 static int
00126 _comp_with_mask(void *addr, void *dest, u_int mask) {
00127 
00128         /* Mask length of zero matches everything */
00129         if (mask == 0)
00130                 return (1);
00131 
00132         if (memcmp(addr, dest, mask / 8) == 0) {
00133                 int n = mask / 8;
00134                 int m = ((~0) << (8 - (mask % 8)));
00135 
00136                 if ((mask % 8) == 0 ||
00137                     (((u_char *)addr)[n] & m) == (((u_char *)dest)[n] & m))
00138                         return (1);
00139         }
00140         return (0);
00141 }
00142 
00143 isc_result_t
00144 isc_radix_create(isc_mem_t *mctx, isc_radix_tree_t **target, int maxbits) {
00145         isc_radix_tree_t *radix;
00146 
00147         REQUIRE(target != NULL && *target == NULL);
00148 
00149         radix = isc_mem_get(mctx, sizeof(isc_radix_tree_t));
00150         if (radix == NULL)
00151                 return (ISC_R_NOMEMORY);
00152 
00153         radix->mctx = NULL;
00154         isc_mem_attach(mctx, &radix->mctx);
00155         radix->maxbits = maxbits;
00156         radix->head = NULL;
00157         radix->num_active_node = 0;
00158         radix->num_added_node = 0;
00159         RUNTIME_CHECK(maxbits <= RADIX_MAXBITS); /* XXX */
00160         radix->magic = RADIX_TREE_MAGIC;
00161         *target = radix;
00162         return (ISC_R_SUCCESS);
00163 }
00164 
00165 /*
00166  * if func is supplied, it will be called as func(node->data)
00167  * before deleting the node
00168  */
00169 
00170 static void
00171 _clear_radix(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) {
00172 
00173         REQUIRE(radix != NULL);
00174 
00175         if (radix->head != NULL) {
00176                 isc_radix_node_t *Xstack[RADIX_MAXBITS+1];
00177                 isc_radix_node_t **Xsp = Xstack;
00178                 isc_radix_node_t *Xrn = radix->head;
00179 
00180                 while (Xrn != NULL) {
00181                         isc_radix_node_t *l = Xrn->l;
00182                         isc_radix_node_t *r = Xrn->r;
00183 
00184                         if (Xrn->prefix != NULL) {
00185                                 _deref_prefix(Xrn->prefix);
00186                                 if (func != NULL)
00187                                         func(Xrn->data);
00188                         } else {
00189                                 INSIST(Xrn->data[0] == NULL &&
00190                                        Xrn->data[1] == NULL &&
00191                                        Xrn->data[2] == NULL &&
00192                                        Xrn->data[3] == NULL);
00193                         }
00194 
00195                         isc_mem_put(radix->mctx, Xrn, sizeof(*Xrn));
00196                         radix->num_active_node--;
00197 
00198                         if (l != NULL) {
00199                                 if (r != NULL) {
00200                                         *Xsp++ = r;
00201                                 }
00202                                 Xrn = l;
00203                         } else if (r != NULL) {
00204                                 Xrn = r;
00205                         } else if (Xsp != Xstack) {
00206                                 Xrn = *(--Xsp);
00207                         } else {
00208                                 Xrn = NULL;
00209                         }
00210                 }
00211         }
00212         RUNTIME_CHECK(radix->num_active_node == 0);
00213 }
00214 
00215 
00216 void
00217 isc_radix_destroy(isc_radix_tree_t *radix, isc_radix_destroyfunc_t func) {
00218         REQUIRE(radix != NULL);
00219         _clear_radix(radix, func);
00220         isc_mem_putanddetach(&radix->mctx, radix, sizeof(*radix));
00221 }
00222 
00223 
00224 /*
00225  * func will be called as func(node->prefix, node->data)
00226  */
00227 void
00228 isc_radix_process(isc_radix_tree_t *radix, isc_radix_processfunc_t func) {
00229         isc_radix_node_t *node;
00230 
00231         REQUIRE(func != NULL);
00232 
00233         RADIX_WALK(radix->head, node) {
00234                 func(node->prefix, node->data);
00235         } RADIX_WALK_END;
00236 }
00237 
00238 
00239 isc_result_t
00240 isc_radix_search(isc_radix_tree_t *radix, isc_radix_node_t **target,
00241                  isc_prefix_t *prefix)
00242 {
00243         isc_radix_node_t *node;
00244         isc_radix_node_t *stack[RADIX_MAXBITS + 1];
00245         u_char *addr;
00246         isc_uint32_t bitlen;
00247         int toff = -1, cnt = 0;
00248 
00249         REQUIRE(radix != NULL);
00250         REQUIRE(prefix != NULL);
00251         REQUIRE(target != NULL && *target == NULL);
00252         RUNTIME_CHECK(prefix->bitlen <= radix->maxbits);
00253 
00254         *target = NULL;
00255 
00256         if (radix->head == NULL) {
00257                 return (ISC_R_NOTFOUND);
00258         }
00259 
00260         node = radix->head;
00261         addr = isc_prefix_touchar(prefix);
00262         bitlen = prefix->bitlen;
00263 
00264         while (node->bit < bitlen) {
00265                 if (node->prefix)
00266                         stack[cnt++] = node;
00267 
00268                 if (BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
00269                         node = node->r;
00270                 else
00271                         node = node->l;
00272 
00273                 if (node == NULL)
00274                         break;
00275         }
00276 
00277         if (node && node->prefix)
00278                 stack[cnt++] = node;
00279 
00280         while (cnt-- > 0) {
00281                 node = stack[cnt];
00282 
00283                 if (prefix->bitlen < node->bit)
00284                         continue;
00285 
00286                 if (_comp_with_mask(isc_prefix_tochar(node->prefix),
00287                                     isc_prefix_tochar(prefix),
00288                                     node->prefix->bitlen))
00289                 {
00290                         int off = ISC_RADIX_OFF(prefix);
00291                         if (node->node_num[off] != -1 &&
00292                             ((*target == NULL) ||
00293                              (*target)->node_num[toff] > node->node_num[off]))
00294                         {
00295                                 *target = node;
00296                                 toff = off;
00297                         }
00298                 }
00299         }
00300 
00301         if (*target == NULL) {
00302                 return (ISC_R_NOTFOUND);
00303         } else {
00304                 return (ISC_R_SUCCESS);
00305         }
00306 }
00307 
00308 isc_result_t
00309 isc_radix_insert(isc_radix_tree_t *radix, isc_radix_node_t **target,
00310                  isc_radix_node_t *source, isc_prefix_t *prefix)
00311 {
00312         isc_radix_node_t *node, *new_node, *parent, *glue = NULL;
00313         u_char *addr, *test_addr;
00314         isc_uint32_t bitlen, fam, check_bit, differ_bit;
00315         isc_uint32_t i, j, r;
00316         isc_result_t result;
00317 
00318         REQUIRE(radix != NULL);
00319         REQUIRE(target != NULL && *target == NULL);
00320         REQUIRE(prefix != NULL || (source != NULL && source->prefix != NULL));
00321         RUNTIME_CHECK(prefix == NULL || prefix->bitlen <= radix->maxbits);
00322 
00323         if (prefix == NULL)
00324                 prefix = source->prefix;
00325 
00326         INSIST(prefix != NULL);
00327 
00328         bitlen = prefix->bitlen;
00329         fam = prefix->family;
00330 
00331         if (radix->head == NULL) {
00332                 node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t));
00333                 if (node == NULL)
00334                         return (ISC_R_NOMEMORY);
00335                 node->bit = bitlen;
00336                 for (i = 0; i < 4; i++)
00337                         node->node_num[i] = -1;
00338                 node->prefix = NULL;
00339                 result = _ref_prefix(radix->mctx, &node->prefix, prefix);
00340                 if (result != ISC_R_SUCCESS) {
00341                         isc_mem_put(radix->mctx, node,
00342                                     sizeof(isc_radix_node_t));
00343                         return (result);
00344                 }
00345                 node->parent = NULL;
00346                 node->l = node->r = NULL;
00347                 if (source != NULL) {
00348                         /*
00349                          * If source is non-NULL, then we're merging in a
00350                          * node from an existing radix tree.  To keep
00351                          * the node_num values consistent, the calling
00352                          * function will add the total number of nodes
00353                          * added to num_added_node at the end of
00354                          * the merge operation--we don't do it here.
00355                          */
00356                         for (i = 0; i < 4; i++) {
00357                                 if (source->node_num[i] != -1)
00358                                         node->node_num[i] =
00359                                                 radix->num_added_node +
00360                                                 source->node_num[i];
00361                                 node->data[i] = source->data[i];
00362                         }
00363                 } else {
00364                         int next = ++radix->num_added_node;
00365                         if (fam == AF_UNSPEC) {
00366                                 /* "any" or "none" */
00367                                 for (i = 0; i < 4; i++)
00368                                         node->node_num[i] = next;
00369                         } else {
00370                                 node->node_num[ISC_RADIX_OFF(prefix)] = next;
00371                         }
00372 
00373                         memset(node->data, 0, sizeof(node->data));
00374                 }
00375                 radix->head = node;
00376                 radix->num_active_node++;
00377                 *target = node;
00378                 return (ISC_R_SUCCESS);
00379         }
00380 
00381         addr = isc_prefix_touchar(prefix);
00382         node = radix->head;
00383 
00384         while (node->bit < bitlen || node->prefix == NULL) {
00385                 if (node->bit < radix->maxbits &&
00386                     BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
00387                 {
00388                         if (node->r == NULL)
00389                                 break;
00390                         node = node->r;
00391                 } else {
00392                         if (node->l == NULL)
00393                                 break;
00394                         node = node->l;
00395                 }
00396 
00397                 INSIST(node != NULL);
00398         }
00399 
00400         INSIST(node->prefix != NULL);
00401 
00402         test_addr = isc_prefix_touchar(node->prefix);
00403         /* Find the first bit different. */
00404         check_bit = (node->bit < bitlen) ? node->bit : bitlen;
00405         differ_bit = 0;
00406         for (i = 0; i*8 < check_bit; i++) {
00407                 if ((r = (addr[i] ^ test_addr[i])) == 0) {
00408                         differ_bit = (i + 1) * 8;
00409                         continue;
00410                 }
00411                 /* I know the better way, but for now. */
00412                 for (j = 0; j < 8; j++) {
00413                         if (BIT_TEST (r, (0x80 >> j)))
00414                                 break;
00415                 }
00416                 /* Must be found. */
00417                 INSIST(j < 8);
00418                 differ_bit = i * 8 + j;
00419                 break;
00420         }
00421 
00422         if (differ_bit > check_bit)
00423                 differ_bit = check_bit;
00424 
00425         parent = node->parent;
00426         while (parent != NULL && parent->bit >= differ_bit) {
00427                 node = parent;
00428                 parent = node->parent;
00429         }
00430 
00431         if (differ_bit == bitlen && node->bit == bitlen) {
00432                 if (node->prefix != NULL) {
00433                         /* Set node_num only if it hasn't been set before */
00434                         if (source != NULL) {
00435                                 /* Merging nodes */
00436                                 for (i = 0; i < 4; i++) {
00437                                         if (node->node_num[i] == -1 &&
00438                                             source->node_num[i] != -1) {
00439                                                 node->node_num[i] =
00440                                                         radix->num_added_node +
00441                                                         source->node_num[i];
00442                                                 node->data[i] = source->data[i];
00443                                         }
00444                                 }
00445                         } else {
00446                                 if (fam == AF_UNSPEC) {
00447                                         /* "any" or "none" */
00448                                         int next = radix->num_added_node + 1;
00449                                         for (i = 0; i < 4; i++)  {
00450                                                 if (node->node_num[i] == -1) {
00451                                                         node->node_num[i] =
00452                                                                 next;
00453                                                         radix->num_added_node =
00454                                                                 next;
00455                                                 }
00456                                         }
00457                                 } else {
00458                                         int off = ISC_RADIX_OFF(prefix);
00459                                         if (node->node_num[off] == -1)
00460                                                 node->node_num[off] =
00461                                                         ++radix->num_added_node;
00462                                 }
00463                         }
00464                         *target = node;
00465                         return (ISC_R_SUCCESS);
00466                 } else {
00467                         result = _ref_prefix(radix->mctx,
00468                                              &node->prefix, prefix);
00469                         if (result != ISC_R_SUCCESS)
00470                                 return (result);
00471                 }
00472                 INSIST(node->data[0] == NULL && node->node_num[0] == -1 &&
00473                        node->data[1] == NULL && node->node_num[1] == -1 &&
00474                        node->data[2] == NULL && node->node_num[2] == -1 &&
00475                        node->data[3] == NULL && node->node_num[3] == -1);
00476                 if (source != NULL) {
00477                         /* Merging node */
00478                         for (i = 0; i < 4; i++) {
00479                                 int cur = radix->num_added_node;
00480                                 if (source->node_num[i] != -1) {
00481                                         node->node_num[i] =
00482                                                 source->node_num[i] + cur;
00483                                         node->data[i] = source->data[i];
00484                                 }
00485                         }
00486                 } else {
00487                         int next = ++radix->num_added_node;
00488                         if (fam == AF_UNSPEC) {
00489                                 /* "any" or "none" */
00490                                 for (i = 0; i < 4; i++)
00491                                         node->node_num[i] = next;
00492                         } else {
00493                                 node->node_num[ISC_RADIX_OFF(prefix)] = next;
00494                         }
00495                 }
00496                 *target = node;
00497                 return (ISC_R_SUCCESS);
00498         }
00499 
00500         new_node = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t));
00501         if (new_node == NULL)
00502                 return (ISC_R_NOMEMORY);
00503         if (node->bit != differ_bit && bitlen != differ_bit) {
00504                 glue = isc_mem_get(radix->mctx, sizeof(isc_radix_node_t));
00505                 if (glue == NULL) {
00506                         isc_mem_put(radix->mctx, new_node,
00507                                     sizeof(isc_radix_node_t));
00508                         return (ISC_R_NOMEMORY);
00509                 }
00510         }
00511         new_node->bit = bitlen;
00512         new_node->prefix = NULL;
00513         result = _ref_prefix(radix->mctx, &new_node->prefix, prefix);
00514         if (result != ISC_R_SUCCESS) {
00515                 isc_mem_put(radix->mctx, new_node, sizeof(isc_radix_node_t));
00516                 if (glue != NULL)
00517                         isc_mem_put(radix->mctx, glue,
00518                                     sizeof(isc_radix_node_t));
00519                 return (result);
00520         }
00521         new_node->parent = NULL;
00522         new_node->l = new_node->r = NULL;
00523         for (i = 0; i < 4; i++)
00524                 new_node->node_num[i] = -1;
00525         radix->num_active_node++;
00526 
00527         if (source != NULL) {
00528                 /* Merging node */
00529                 for (i = 0; i < 4; i++) {
00530                         int cur = radix->num_added_node;
00531                         if (source->node_num[i] != -1) {
00532                                 new_node->node_num[i] =
00533                                         source->node_num[i] + cur;
00534                                 new_node->data[i] = source->data[i];
00535                         }
00536                 }
00537         } else {
00538                 int next = ++radix->num_added_node;
00539                 if (fam == AF_UNSPEC) {
00540                         /* "any" or "none" */
00541                         for (i = 0; i < 4; i++)
00542                                 new_node->node_num[i] = next;
00543                 } else {
00544                         new_node->node_num[ISC_RADIX_OFF(prefix)] = next;
00545                 }
00546                 memset(new_node->data, 0, sizeof(new_node->data));
00547         }
00548 
00549         if (node->bit == differ_bit) {
00550                 INSIST(glue == NULL);
00551                 new_node->parent = node;
00552                 if (node->bit < radix->maxbits &&
00553                     BIT_TEST(addr[node->bit >> 3], 0x80 >> (node->bit & 0x07)))
00554                 {
00555                         INSIST(node->r == NULL);
00556                         node->r = new_node;
00557                 } else {
00558                         INSIST(node->l == NULL);
00559                         node->l = new_node;
00560                 }
00561                 *target = new_node;
00562                 return (ISC_R_SUCCESS);
00563         }
00564 
00565         if (bitlen == differ_bit) {
00566                 INSIST(glue == NULL);
00567                 if (bitlen < radix->maxbits &&
00568                     BIT_TEST(test_addr[bitlen >> 3], 0x80 >> (bitlen & 0x07))) {
00569                         new_node->r = node;
00570                 } else {
00571                         new_node->l = node;
00572                 }
00573                 new_node->parent = node->parent;
00574                 if (node->parent == NULL) {
00575                         INSIST(radix->head == node);
00576                         radix->head = new_node;
00577                 } else if (node->parent->r == node) {
00578                         node->parent->r = new_node;
00579                 } else {
00580                         node->parent->l = new_node;
00581                 }
00582                 node->parent = new_node;
00583         } else {
00584                 INSIST(glue != NULL);
00585                 glue->bit = differ_bit;
00586                 glue->prefix = NULL;
00587                 glue->parent = node->parent;
00588                 for (i = 0; i < 4; i++) {
00589                         glue->data[i] = NULL;
00590                         glue->node_num[i] = -1;
00591                 }
00592                 radix->num_active_node++;
00593                 if (differ_bit < radix->maxbits &&
00594                     BIT_TEST(addr[differ_bit>>3], 0x80 >> (differ_bit & 07))) {
00595                         glue->r = new_node;
00596                         glue->l = node;
00597                 } else {
00598                         glue->r = node;
00599                         glue->l = new_node;
00600                 }
00601                 new_node->parent = glue;
00602 
00603                 if (node->parent == NULL) {
00604                         INSIST(radix->head == node);
00605                         radix->head = glue;
00606                 } else if (node->parent->r == node) {
00607                         node->parent->r = glue;
00608                 } else {
00609                         node->parent->l = glue;
00610                 }
00611                 node->parent = glue;
00612         }
00613 
00614         *target = new_node;
00615         return (ISC_R_SUCCESS);
00616 }
00617 
00618 void
00619 isc_radix_remove(isc_radix_tree_t *radix, isc_radix_node_t *node) {
00620         isc_radix_node_t *parent, *child;
00621 
00622         REQUIRE(radix != NULL);
00623         REQUIRE(node != NULL);
00624 
00625         if (node->r && node->l) {
00626                 /*
00627                  * This might be a placeholder node -- have to check and
00628                  * make sure there is a prefix associated with it!
00629                  */
00630                 if (node->prefix != NULL)
00631                         _deref_prefix(node->prefix);
00632 
00633                 node->prefix = NULL;
00634                 memset(node->data, 0, sizeof(node->data));
00635                 return;
00636         }
00637 
00638         if (node->r == NULL && node->l == NULL) {
00639                 parent = node->parent;
00640                 _deref_prefix(node->prefix);
00641 
00642                 if (parent == NULL) {
00643                         INSIST(radix->head == node);
00644                         radix->head = NULL;
00645                         isc_mem_put(radix->mctx, node, sizeof(*node));
00646                         radix->num_active_node--;
00647                         return;
00648                 }
00649 
00650                 if (parent->r == node) {
00651                         parent->r = NULL;
00652                         child = parent->l;
00653                 } else {
00654                         INSIST(parent->l == node);
00655                         parent->l = NULL;
00656                         child = parent->r;
00657                 }
00658 
00659                 isc_mem_put(radix->mctx, node, sizeof(*node));
00660                 radix->num_active_node--;
00661 
00662                 if (parent->prefix)
00663                         return;
00664 
00665                 /* We need to remove parent too. */
00666                 if (parent->parent == NULL) {
00667                         INSIST(radix->head == parent);
00668                         radix->head = child;
00669                 } else if (parent->parent->r == parent) {
00670                         parent->parent->r = child;
00671                 } else {
00672                         INSIST(parent->parent->l == parent);
00673                         parent->parent->l = child;
00674                 }
00675 
00676                 child->parent = parent->parent;
00677                 isc_mem_put(radix->mctx, parent, sizeof(*parent));
00678                 radix->num_active_node--;
00679                 return;
00680         }
00681 
00682         if (node->r) {
00683                 child = node->r;
00684         } else {
00685                 INSIST(node->l != NULL);
00686                 child = node->l;
00687         }
00688 
00689         parent = node->parent;
00690         child->parent = parent;
00691 
00692         _deref_prefix(node->prefix);
00693 
00694         if (parent == NULL) {
00695                 INSIST(radix->head == node);
00696                 radix->head = child;
00697                 isc_mem_put(radix->mctx, node, sizeof(*node));
00698                 radix->num_active_node--;
00699                 return;
00700         }
00701 
00702         isc_mem_put(radix->mctx, node, sizeof(*node));
00703         radix->num_active_node--;
00704 
00705         if (parent->r == node) {
00706                 parent->r = child;
00707         } else {
00708                 INSIST(parent->l == node);
00709                 parent->l = child;
00710         }
00711 }
00712 
00713 /*
00714 Local Variables:
00715 c-basic-offset: 4
00716 indent-tabs-mode: t
00717 End:
00718 */

Generated on Tue Apr 28 17:41:05 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha