const char *cached_ntoa(struct in_addr addr) { rb_ntoa_key_t rbk = {0}; rb_ntoa_key_t *_rbk = NULL; rb_tree_node_t *tnode = NULL; rbk.key = addr.s_addr; if(rb_tree_find(&rb_ntoa_tree, &rbk, &tnode) == RB_OK) { _rbk = (rb_ntoa_key_t *)((char *)tnode + sizeof(rb_tree_node_t)); return _rbk->addr; } else { tnode = malloc(sizeof(rb_tree_node_t) + sizeof(rb_ntoa_key_t)); if(tnode) { memset(tnode, 0, sizeof(rb_tree_node_t) + sizeof(rb_ntoa_key_t)); _rbk = (rb_ntoa_key_t *)((char *)tnode + sizeof(rb_tree_node_t)); _rbk->key = addr.s_addr; char *_t = inet_ntoa(addr); memcpy(_rbk->addr, _t, strlen(_t)); if(rb_tree_insert(&rb_ntoa_tree, _rbk, tnode) != RB_OK) { free(tnode); _rbk = NULL; } else { return _rbk->addr; } } } return inet_ntoa(addr); }
status_t memory_pool_unclaim(memory_pool_handle_t handle, void* data) { status_t status = NO_ERROR; rb_tree_node_handle_t node = NULL; int err = 0; if ((NULL == handle) || (NULL == data)) { return ERR_NULL_POINTER; } status = rb_tree_find(handle->claimed, data, &node); if (NO_ERROR != status) { return status; } if (NULL == node) { return ERR_INVALID_ARGUMENT; } err = pthread_mutex_lock(&(handle->mutex)); if (err) { return ERR_MUTEX_ERROR; } status = stack_push(handle->available, data); err = pthread_mutex_unlock(&(handle->mutex)); if (NO_ERROR != status) { return status; } status = rb_tree_remove(handle->claimed, node); if (NO_ERROR != status) { return status; } return NO_ERROR; }
int cached_access(unsigned long key, const char *path) { rb_access_key_t rbk = {0}; rb_access_key_t *_rbk = NULL; rb_tree_node_t *tnode = NULL; rbk.key = key; if(rb_tree_find(&rb_access_tree, &rbk, &tnode) == RB_OK) { _rbk = (rb_access_key_t *)((char *)tnode + sizeof(rb_tree_node_t)); if(now - _rbk->last > 10) { _rbk->last = now; _rbk->exists = access(path, F_OK); } return _rbk->exists; } else { tnode = malloc(sizeof(rb_tree_node_t) + sizeof(rb_access_key_t)); if(tnode) { memset(tnode, 0, sizeof(rb_tree_node_t) + sizeof(rb_access_key_t)); _rbk = (rb_access_key_t *)((char *)tnode + sizeof(rb_tree_node_t)); _rbk->key = key; _rbk->exists = access(path, F_OK); if(rb_tree_insert(&rb_access_tree, _rbk, tnode) != RB_OK) { free(tnode); _rbk = NULL; } else { return _rbk->exists; } } } return -1; }
/* divide rectangle idiv in the list p->rects */ static nlopt_result divide_rect(double *rdiv, params *p) { int i; const int n = p->n; const int L = p->L; double *c = rdiv + 3; /* center of rect to divide */ double *w = c + n; /* widths of rect to divide */ double wmax = w[0]; int imax = 0, nlongest = 0; rb_node *node; for (i = 1; i < n; ++i) if (w[i] > wmax) wmax = w[imax = i]; for (i = 0; i < n; ++i) if (wmax - w[i] <= wmax * EQUAL_SIDE_TOL) ++nlongest; if (p->which_div == 1 || (p->which_div == 0 && nlongest == n)) { /* trisect all longest sides, in increasing order of the average function value along that direction */ double *fv = p->work; int *isort = p->iwork; for (i = 0; i < n; ++i) { if (wmax - w[i] <= wmax * EQUAL_SIDE_TOL) { double csave = c[i]; c[i] = csave - w[i] * THIRD; FUNCTION_EVAL(fv[2*i], c, p, 0); c[i] = csave + w[i] * THIRD; FUNCTION_EVAL(fv[2*i+1], c, p, 0); c[i] = csave; } else { fv[2*i] = fv[2*i+1] = HUGE_VAL; } } sort_fv(n, fv, isort); if (!(node = rb_tree_find(&p->rtree, rdiv))) return NLOPT_FAILURE; for (i = 0; i < nlongest; ++i) { int k; w[isort[i]] *= THIRD; rdiv[0] = rect_diameter(n, w, p); rdiv[2] = p->age++; node = rb_tree_resort(&p->rtree, node); for (k = 0; k <= 1; ++k) { double *rnew; ALLOC_RECT(rnew, L); memcpy(rnew, rdiv, sizeof(double) * L); rnew[3 + isort[i]] += w[isort[i]] * (2*k-1); rnew[1] = fv[2*isort[i]+k]; rnew[2] = p->age++; if (!rb_tree_insert(&p->rtree, rnew)) { free(rnew); return NLOPT_OUT_OF_MEMORY; } } } } else { int k; if (nlongest > 1 && p->which_div == 2) { /* randomly choose longest side */ i = nlopt_iurand(nlongest); for (k = 0; k < n; ++k) if (wmax - w[k] <= wmax * EQUAL_SIDE_TOL) { if (!i) { i = k; break; } --i; } } else i = imax; /* trisect longest side */ if (!(node = rb_tree_find(&p->rtree, rdiv))) return NLOPT_FAILURE; w[i] *= THIRD; rdiv[0] = rect_diameter(n, w, p); rdiv[2] = p->age++; node = rb_tree_resort(&p->rtree, node); for (k = 0; k <= 1; ++k) { double *rnew; ALLOC_RECT(rnew, L); memcpy(rnew, rdiv, sizeof(double) * L); rnew[3 + i] += w[i] * (2*k-1); FUNCTION_EVAL(rnew[1], rnew + 3, p, rnew); rnew[2] = p->age++; if (!rb_tree_insert(&p->rtree, rnew)) { free(rnew); return NLOPT_OUT_OF_MEMORY; } } } return NLOPT_SUCCESS; }
int main(int argc, char **argv) { int N, M; int *k; double kd; rb_tree t; rb_node *n; int i, j; if (argc < 2) { fprintf(stderr, "Usage: redblack_test Ntest [rand seed]\n"); return 1; } N = atoi(argv[1]); k = (int *) malloc(N * sizeof(int)); rb_tree_init(&t, comp); srand((unsigned) (argc > 2 ? atoi(argv[2]) : time(NULL))); for (i = 0; i < N; ++i) { double *newk = (double *) malloc(sizeof(double)); *newk = (k[i] = rand() % N); if (!rb_tree_insert(&t, newk)) { fprintf(stderr, "error in rb_tree_insert\n"); return 1; } if (!rb_tree_check(&t)) { fprintf(stderr, "rb_tree_check_failed after insert!\n"); return 1; } } if (t.N != N) { fprintf(stderr, "incorrect N (%d) in tree (vs. %d)\n", t.N, N); return 1; } for (i = 0; i < N; ++i) { kd = k[i]; if (!rb_tree_find(&t, &kd)) { fprintf(stderr, "rb_tree_find lost %d!\n", k[i]); return 1; } } n = rb_tree_min(&t); for (i = 0; i < N; ++i) { if (!n) { fprintf(stderr, "not enough successors %d\n!", i); return 1; } printf("%d: %g\n", i, n->k[0]); n = rb_tree_succ(n); } if (n) { fprintf(stderr, "too many successors!\n"); return 1; } n = rb_tree_max(&t); for (i = 0; i < N; ++i) { if (!n) { fprintf(stderr, "not enough predecessors %d\n!", i); return 1; } printf("%d: %g\n", i, n->k[0]); n = rb_tree_pred(n); } if (n) { fprintf(stderr, "too many predecessors!\n"); return 1; } for (M = N; M > 0; --M) { int knew = rand() % N; /* random new key */ j = rand() % M; /* random original key to replace */ for (i = 0; i < N; ++i) if (k[i] >= 0) if (j-- == 0) break; if (i >= N) abort(); kd = k[i]; if (!(n = rb_tree_find(&t, &kd))) { fprintf(stderr, "rb_tree_find lost %d!\n", k[i]); return 1; } n->k[0] = knew; if (!rb_tree_resort(&t, n)) { fprintf(stderr, "error in rb_tree_resort\n"); return 1; } if (!rb_tree_check(&t)) { fprintf(stderr, "rb_tree_check_failed after change %d!\n", N - M + 1); return 1; } k[i] = -1 - knew; } if (t.N != N) { fprintf(stderr, "incorrect N (%d) in tree (vs. %d)\n", t.N, N); return 1; } for (i = 0; i < N; ++i) k[i] = -1 - k[i]; /* undo negation above */ for (i = 0; i < N; ++i) { rb_node *le, *gt; double lek, gtk; kd = 0.01 * (rand() % (N * 150) - N * 25); le = rb_tree_find_le(&t, &kd); gt = rb_tree_find_gt(&t, &kd); n = rb_tree_min(&t); lek = le ? le->k[0] : -HUGE_VAL; gtk = gt ? gt->k[0] : +HUGE_VAL; printf("%g <= %g < %g\n", lek, kd, gtk); if (n->k[0] > kd) { if (le) { fprintf(stderr, "found invalid le %g for %g\n", lek, kd); return 1; } if (gt != n) { fprintf(stderr, "gt is not first node for k=%g\n", kd); return 1; } } else { rb_node *succ = n; do { n = succ; succ = rb_tree_succ(n); } while (succ && succ->k[0] <= kd); if (n != le) { fprintf(stderr, "rb_tree_find_le gave wrong result for k=%g\n", kd); return 1; } if (succ != gt) { fprintf(stderr, "rb_tree_find_gt gave wrong result for k=%g\n", kd); return 1; } } } for (M = N; M > 0; --M) { j = rand() % M; for (i = 0; i < N; ++i) if (k[i] >= 0) if (j-- == 0) break; if (i >= N) abort(); kd = k[i]; if (!(n = rb_tree_find(&t, &kd))) { fprintf(stderr, "rb_tree_find lost %d!\n", k[i]); return 1; } n = rb_tree_remove(&t, n); free(n->k); free(n); if (!rb_tree_check(&t)) { fprintf(stderr, "rb_tree_check_failed after remove!\n"); return 1; } k[i] = -1 - k[i]; } if (t.N != 0) { fprintf(stderr, "nonzero N (%d) in tree at end\n", t.N); return 1; } rb_tree_destroy(&t); free(k); printf("SUCCESS.\n"); return 0; }