/* destroy tasknames collection */ void dest_tasknames_collection(void) { assert(libraryStatus == initialized); #if (library_TESTING) printout_all_tasknames(); printout_nonspecified_tasknames(); #endif RBTreeDestroy(all_tasknames); RBTreeDestroy(nonspecified_tasknames); libraryStatus = uninitialized; }
int main() { int w, h, n, x; char Cmd[2]; scanf("%d %d %d", &w, &h, &n); RBTreeInitialize(&SetH); RBTreeInitialize(&SetV); RBTreeInitialize(&LenH); RBTreeInitialize(&LenV); RBTreeAdd(&SetH, 0); RBTreeAdd(&SetH, h); RBTreeAdd(&SetV, 0); RBTreeAdd(&SetV, w); RBTreeAdd(&LenH, h); RBTreeAdd(&LenV, w); while(n--) { scanf("%s %d", Cmd, &x); if(Cmd[0] == 'H') { struct RBNode_t *node = (struct RBNode_t *)malloc(sizeof(struct RBNode_t)); node->mKey.mPrimaryVal = x; RBTreeInsert(&SetH, node); struct RBNode_t *p = RBTreePredecessor(node, &SetH.mSentinelLeaf); struct RBNode_t *s = RBTreeSuccessor(node, &SetH.mSentinelLeaf); RBTreeDel(&LenH, s->mKey.mPrimaryVal - p->mKey.mPrimaryVal); RBTreeAdd(&LenH, x - p->mKey.mPrimaryVal); RBTreeAdd(&LenH, s->mKey.mPrimaryVal - x); } else { struct RBNode_t *node = (struct RBNode_t *)malloc(sizeof(struct RBNode_t)); node->mKey.mPrimaryVal = x; RBTreeInsert(&SetV, node); struct RBNode_t *p = RBTreePredecessor(node, &SetV.mSentinelLeaf); struct RBNode_t *s = RBTreeSuccessor(node, &SetV.mSentinelLeaf); RBTreeDel(&LenV, s->mKey.mPrimaryVal - p->mKey.mPrimaryVal); RBTreeAdd(&LenV, x - p->mKey.mPrimaryVal); RBTreeAdd(&LenV, s->mKey.mPrimaryVal - x); } long long Ans = RBTreeMaximum(LenH.mTreeRoot, &LenH.mSentinelLeaf)->mKey.mPrimaryVal; Ans *= RBTreeMaximum(LenV.mTreeRoot, &LenV.mSentinelLeaf)->mKey.mPrimaryVal; printf("%I64d\n", Ans); } RBTreeDestroy(&SetH); RBTreeDestroy(&SetV); RBTreeDestroy(&LenH); RBTreeDestroy(&LenV); return 0; }
static void cfs_destroy_sched_data(void *data) { cfs_data_t *cfs_data = data; for (int i = 0; i < cfs_data->cfs_kthread_count; ++i) { RBTreeDestroy(cfs_data->cfs_kthreads[i].tree); } free(cfs_data->cfs_kthreads); free(cfs_data); }
void close_client_connection(Maintainer* maintainer, int current_socket, Node* node, int exception) { getpeername(current_socket, (struct sockaddr*)&(maintainer->address), (socklen_t*)&(maintainer->addrlen)); logger("<Server><close_client_connection>Host disconnected, ip %s, port %d \n", inet_ntoa(maintainer->address.sin_addr), ntohs(maintainer->address.sin_port)); RBDelete(maintainer->nodes_ip,RBExactQuery(maintainer->nodes_ip, &(maintainer->address.sin_addr.s_addr))); /*TODO memory leak?*/ FD_CLR(current_socket, &(maintainer->fd_read_set)); FD_CLR(current_socket, &(maintainer->fd_exception_set)); FD_CLR(current_socket, &(maintainer->fd_write_set)); if(maintainer->max_sd == current_socket) { maintainer->max_sd = maintainer->master_socket; struct Nodes_ll* iterator = maintainer->clients; while(iterator != NULL) { if((iterator->node->socket_fd > maintainer->max_sd) && (iterator->node->socket_fd != current_socket)) maintainer->max_sd = iterator->node->socket_fd; iterator = iterator->next; } } struct Files_ll* iterator= node->node_files; while(iterator != NULL) { --(iterator->file->num_of_owners); struct Nodes_ll* jterator = iterator->file->owners; struct Nodes_ll* pjterator = iterator->file->owners; while(jterator != NULL) { if(jterator->node->socket_fd == current_socket) { if(jterator != iterator->file->owners) { pjterator->next = jterator->next; myfree(jterator); break; } else { iterator->file->owners = iterator->file->owners->next; } } if(jterator != iterator->file->owners) pjterator = pjterator->next; jterator = jterator->next; } struct Files_ll* tmp = iterator; iterator = iterator->next; myfree(tmp); } RBTreeDestroy(node->requests); /*TODO memory leak?*/ node->socket_fd = -1; close(current_socket); }
int main(int argc, char** argv) { int option=0; int64_t newKey,newKey2; rb_red_blk_node* newNode; rb_red_blk_tree* tree; int64_t* array = 0; int64_t* array2 = 0; unsigned int N = 65536; //total number of elements to insert unsigned int M = 16384; //number of elements to delete from the beginning unsigned int M2 = 16384; //number of elements to delete from the end int i; unsigned int j; time_t t1 = time(0); unsigned int seed = t1; double par = 2.5; for(i=1;i<argc;i++) if(argv[i][0] == '-') switch(argv[i][1]) { case 'N': N = atoi(argv[i+1]); break; case 'M': M = atoi(argv[i+1]); if(i+2 < argc) { if(isdigit(argv[i+2][0])) M2 = atoi(argv[i+2]); else M2 = M; } else M2 = M; break; case 's': seed = atoi(argv[i+1]); break; case 'p': par = atof(argv[i+1]); break; default: fprintf(stderr,"unrecognized parameter: %s!\n",argv[i]); break; } if(M + M2 >= N) { fprintf(stderr,"Error: number of elements to delete (%u + %u) is more than the total number of elements (%u)!\n", M,M2,N); return 1; } tree=RBTreeCreate(CmpInt64,NullFunction,NullFunction,NullFunction,NullFunction,DFInt64,&par); array = SafeMalloc(sizeof(int64_t)*N); for(j=0;j<N;j++) { array[j] = ((int64_t)rand())*((int64_t)rand())*((int64_t)rand()); RBTreeInsert(tree,(void*)(array[j]),0); } for(j=0;j<M;j++) { newNode = RBExactQuery(tree,(void*)(array[j])); if(!newNode) { fprintf(stderr,"Error: node not found!\n"); goto rbt_end; } RBDelete(tree,newNode); } for(j=N-M2;j<N;j++) { newNode = RBExactQuery(tree,(void*)(array[j])); if(!newNode) { fprintf(stderr,"Error: node not found!\n"); goto rbt_end; } RBDelete(tree,newNode); } N = N-M2-M; array2 = array+M; quicksort(array2,0,N); j=0; newNode = TreeFirst(tree); double cdf = 0.0; do { int64_t v1 = (int64_t)(newNode->key); if(v1 != array2[j]) { fprintf(stderr,"error: %d != %d!\n",v1,array2[j]); break; } double cdf2 = GetNodeRank(tree,newNode); double diff = fabs(cdf2-cdf); if(diff > EPSILON) { fprintf(stderr,"wrong cdf value: %g != %g (diff: %g)!\n",cdf,cdf2,diff); break; } j++; cdf += DFInt64((void*)array2[j],&par); newNode = TreeSuccessor(tree,newNode); } while(newNode != tree->nil && j<N); if( !(newNode == tree->nil && j == N) ) { fprintf(stderr,"error: tree or array too short / long!\n"); } rbt_end: RBTreeDestroy(tree); free(array); time_t t2 = time(0); fprintf(stderr,"runtime: %u\n",(unsigned int)(t2-t1)); return 0; }
static SparseMatrix get_overlap_graph(int dim, int n, real *x, real *width, int check_overlap_only){ /* if check_overlap_only = TRUE, we only check whether there is one overlap */ scan_point *scanpointsx, *scanpointsy; int i, k, neighbor; SparseMatrix A = NULL, B = NULL; rb_red_blk_node *newNode, *newNode0, *newNode2 = NULL; rb_red_blk_tree* treey; real one = 1; A = SparseMatrix_new(n, n, 1, MATRIX_TYPE_REAL, FORMAT_COORD); scanpointsx = N_GNEW(2*n,scan_point); for (i = 0; i < n; i++){ scanpointsx[2*i].node = i; scanpointsx[2*i].x = x[i*dim] - width[i*dim]; scanpointsx[2*i].status = INTV_OPEN; scanpointsx[2*i+1].node = i+n; scanpointsx[2*i+1].x = x[i*dim] + width[i*dim]; scanpointsx[2*i+1].status = INTV_CLOSE; } qsort(scanpointsx, 2*n, sizeof(scan_point), comp_scan_points); scanpointsy = N_GNEW(2*n,scan_point); for (i = 0; i < n; i++){ scanpointsy[i].node = i; scanpointsy[i].x = x[i*dim+1] - width[i*dim+1]; scanpointsy[i].status = INTV_OPEN; scanpointsy[i+n].node = i; scanpointsy[i+n].x = x[i*dim+1] + width[i*dim+1]; scanpointsy[i+n].status = INTV_CLOSE; } treey = RBTreeCreate(NodeComp,NodeDest,InfoDest,NodePrint,InfoPrint); for (i = 0; i < 2*n; i++){ #ifdef DEBUG_RBTREE fprintf(stderr," k = %d node = %d x====%f\n",(scanpointsx[i].node)%n, (scanpointsx[i].node), (scanpointsx[i].x)); #endif k = (scanpointsx[i].node)%n; if (scanpointsx[i].status == INTV_OPEN){ #ifdef DEBUG_RBTREE fprintf(stderr, "inserting..."); treey->PrintKey(&(scanpointsy[k])); #endif RBTreeInsert(treey, &(scanpointsy[k]), NULL); /* add both open and close int for y */ #ifdef DEBUG_RBTREE fprintf(stderr, "inserting2..."); treey->PrintKey(&(scanpointsy[k+n])); #endif RBTreeInsert(treey, &(scanpointsy[k+n]), NULL); } else { real bsta, bbsta, bsto, bbsto; int ii; assert(scanpointsx[i].node >= n); newNode = newNode0 = RBExactQuery(treey, &(scanpointsy[k + n])); ii = ((scan_point *)newNode->key)->node; assert(ii < n); bsta = scanpointsy[ii].x; bsto = scanpointsy[ii+n].x; #ifdef DEBUG_RBTREE fprintf(stderr, "poping..%d....yinterval={%f,%f}\n", scanpointsy[k + n].node, bsta, bsto); treey->PrintKey(newNode->key); #endif assert(treey->nil != newNode); while ((newNode) && ((newNode = TreePredecessor(treey, newNode)) != treey->nil)){ neighbor = (((scan_point *)newNode->key)->node)%n; bbsta = scanpointsy[neighbor].x; bbsto = scanpointsy[neighbor+n].x;/* the y-interval of the node that has one end of the interval lower than the top of the leaving interval (bsto) */ #ifdef DEBUG_RBTREE fprintf(stderr," predecessor is node %d y = %f\n", ((scan_point *)newNode->key)->node, ((scan_point *)newNode->key)->x); #endif if (neighbor != k){ if (ABS(0.5*(bsta+bsto) - 0.5*(bbsta+bbsto)) < 0.5*(bsto-bsta) + 0.5*(bbsto-bbsta)){/* if the distance of the centers of the interval is less than sum of width, we have overlap */ A = SparseMatrix_coordinate_form_add_entries(A, 1, &neighbor, &k, &one); #ifdef DEBUG_RBTREE fprintf(stderr,"====================================== %d %d\n",k,neighbor); #endif if (check_overlap_only) goto check_overlap_RETURN; } } else { newNode2 = newNode; } } #ifdef DEBUG_RBTREE fprintf(stderr, "deleteing..."); treey->PrintKey(newNode0->key); #endif if (newNode0) RBDelete(treey,newNode0); if (newNode2 && newNode2 != treey->nil && newNode2 != newNode0) { #ifdef DEBUG_RBTREE fprintf(stderr, "deleteing2..."); treey->PrintKey(newNode2->key); #endif if (newNode0) RBDelete(treey,newNode2); } } } check_overlap_RETURN: FREE(scanpointsx); FREE(scanpointsy); RBTreeDestroy(treey); B = SparseMatrix_from_coordinate_format(A); SparseMatrix_delete(A); A = SparseMatrix_symmetrize(B, FALSE); SparseMatrix_delete(B); if (Verbose) fprintf(stderr, "found %d clashes\n", A->nz); return A; }
void recreate_black() { RBTreeDestroy(black); black = RBTreeCreate(IntComp,IntDest,InfoDest,IntPrint,InfoPrint); }
ssd_cache_handle_t sstack_ssd_cache_init(char *path, int64_t size, log_ctx_t *ctx) { ssd_cache_handle_t handle; ssd_cache_struct_t cache_struct; ssd_cachedev_info_t *info = NULL; int ret = -1; // Parameter validation if (NULL == path || size < 0) { sfs_log(ctx, SFS_ERR, "%s: Invalid parameter specified \n", __FUNCTION__); errno = EINVAL; return -1; } // NOTE: // Populate local data structure and copy this to ssd_caches. // This is to use pthread spinlock instead of mutex and limit // critical section cache_struct.handle = handle; info = ssd_create_cachedev(path, size, ctx); if (NULL == info) { sfs_log(ctx, SFS_ERR, "%s: Failed to create cachedev. Error = %d \n", __FUNCTION__, errno); return -1; } cache_struct.stats.inuse = 0; // Get number of inodes in the file system cache_struct.stats.num_cachelines = info->num_cachelines; strncpy((char *) &cache_struct.mountpt, info->mntpnt, PATH_MAX); // Get cache handle handle = get_next_ssd_cache_handle(); if (handle == -1) { sfs_log(ctx, SFS_ERR, "%s: get_next_ssd_cache_handle returned error. " "Either max cache devices are under use or fatal " "error.\n", __FUNCTION__); errno = ENOENT; return -1; } // Create ssdmd tree and LRU tree for the SSD cache device cache_struct.md_tree = RBTreeCreate(md_comp_func, md_destroy_func, NULL, NULL, NULL); if (NULL == cache_struct.md_tree) { sfs_log(ctx, SFS_ERR, "%s: Failed to allocate memory for md_tree \n", __FUNCTION__); // FIXME: // Implement and call free_ssd_cache_handle(handle); return -1; } pthread_spin_init(&cache_struct.md_lock, PTHREAD_PROCESS_PRIVATE); cache_struct.lru_tree = RBTreeCreate(lru_comp_func, lru_destroy_func, NULL, NULL, NULL); if (NULL == cache_struct.lru_tree) { sfs_log(ctx, SFS_ERR, "%s: Failed to allocate memory for lru_tree \n", __FUNCTION__); RBTreeDestroy(cache_struct.md_tree); pthread_spin_destroy(&cache_struct.md_lock); // FIXME: // Implement and call free_ssd_cache_handle(handle); return -1; } pthread_spin_init(&cache_struct.lru_lock, PTHREAD_PROCESS_PRIVATE); // Create ce_bitmap cache_struct.ce_bitmap = sfs_init_bitmap( cache_struct.stats.num_cachelines, ctx); if (ret == -1) { RBTreeDestroy(cache_struct.md_tree); pthread_spin_destroy(&cache_struct.md_lock); pthread_spin_destroy(&cache_struct.lru_lock); // FIXME: // Implement and call free_ssd_cache_handle(handle); return -1; } pthread_spin_lock(&cache_list_lock); memcpy((void *) &ssd_caches[handle], &cache_struct, sizeof(ssd_cache_struct_t)); pthread_spin_init(&ssd_caches[handle].stats.lock, PTHREAD_PROCESS_PRIVATE); pthread_spin_unlock(&cache_list_lock); return 0; }
void circ_destroy(void *node) { circ_tree_node *c_node = (circ_tree_node *) node; if (c_node->type == TOP_LEVEL) //destroy the contained tree as well if top level RBTreeDestroy(c_node->data.tree); free(c_node); }
void render(PaletteRef *raster, int lineWidth, int numLines, const rb_red_blk_tree *scanLinePrimBuckets){ static OntoProj screenPlaneData = {offsetof(Point, z), 0}; static const Transformation screenPlane = {(TransformationF)(&snapOntoProj), &screenPlaneData}; { int line; rb_red_blk_tree activePrimSet; ActiveEdgeList ael = freshAEL(); rb_red_blk_map_tree inFlags; rb_red_blk_tree deFlags; /* This ensures that both trees are initialized and in a cleared state */ RBTreeMapInit(&inFlags, pointerDiffF, NULL, &RBMapNodeAlloc, NULL); RBTreeInit(&deFlags, pointerDiffF, NULL, &RBNodeAlloc); RBTreeInit(&activePrimSet, pointerDiffF, NULL, &RBNodeAlloc); dPrintf(("Scanning line: 0\n")); for(line = 0; line < numLines; (++line), (raster += lineWidth)) { rb_red_blk_node *primIt, *p = NULL, *nextP; dPrintf(("\tUpdating activePrimSet\n")); for (primIt = activePrimSet.first; primIt != activePrimSet.sentinel; (p = primIt), (primIt = nextP)) { const Primitive* prim = primIt->key; const int top = roundOwn(topMostPoint(prim)); nextP = TreeSuccessor(&activePrimSet, primIt); if(top < line){ #ifndef NDEBUG { const int bottom = roundOwn(bottomMostPoint(prim)); dPrintf(("\t\t%d -> %d ( %s ) is not valid here: %d\n",top,bottom,fmtColor(prim->color), line)); } #endif RBDelete(&activePrimSet, primIt); primIt = p; /* We don't want to advance p into garbage data */ } } { const rb_red_blk_tree *bucket = scanLinePrimBuckets + line; const rb_red_blk_node *node; for(node = bucket->first; node != bucket->sentinel; node = TreeSuccessor(bucket, node)) { Primitive * prim = node->key; #ifndef NDEBUG { const int top = roundOwn(topMostPoint(prim)), bottom = roundOwn(bottomMostPoint(prim)); dPrintf(("\t\t%d -> %d ( %s ) is added here: %d\n",top,bottom,fmtColor(prim->color), line)); } #endif RBTreeInsert(&activePrimSet, prim); } } stepEdges(&ael, &activePrimSet); { int curPixel = 0; const Primitive *curDraw = NULL; EdgeListEntry *nextEdge; LinkN* i = ael.activeEdges; if(i){ nextEdge = i->data; while(nextEdge && curPixel < lineWidth){ EdgeListEntry *const startEdge = nextEdge; Primitive *const startOwner = startEdge->owner; int startX = roundOwn(getSmartXForLine(startEdge, line)), nextX; rb_red_blk_map_node *inFlag = (rb_red_blk_map_node *)RBExactQuery((rb_red_blk_tree*)(&inFlags), startOwner); if(inFlag){ static Point localPoints[6]; /* We don't recurse, so this is fine */ static Edge flatHere = {localPoints, localPoints + 1}, flatIn = {localPoints + 2, localPoints + 3}, vert = {localPoints + 4, localPoints + 5}; const EdgeListEntry *const edgeInEntry = inFlag->info; Point **const edgeHere = startEdge->edge, **edgeIn = edgeInEntry->edge; const Point *const s = edgeHere[START], *const e = edgeHere[END]; Point here; bool sV, eV, v; float dotH, dotIn; transformEdge(&screenPlane, edgeHere, flatHere); transformEdge(&screenPlane, edgeIn, flatIn); INIT_POINT(here, startX, line, 0); sV = contains(edgeIn, s); eV = contains(edgeIn, e); v = (sV || eV) && contains(flatIn, &here) && contains(flatHere, &here) && (startOwner->arity != 1); vert[START] = &here; INIT_POINT(*(vert[END]), startX, line+1, 0); dotH = v ? dotEdge(vert, flatHere) : 0; dotIn = v ? dotEdge(vert, flatIn) : 0; if(!v || dotH * dotIn > 0){ dPrintf(("\tNot *in* old %s at %f\n", fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); RBSetAdd(&deFlags, startOwner); } else { dPrintf(("\tFound horizontal vertex %s at %f. Don't delete it yet\n",fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); } } else { dPrintf(("\tNow *in* new %s at %f\n",fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); /* This might happen if a polygon is parallel to the x-axis */ RBMapPut(&inFlags, startOwner, startEdge); } if(curPixel < startX){ dPrintf(("\tcurPixel has fallen behind, dragging from %d to %d\n",curPixel, startX)); curPixel = startX; } i = i->tail; if(i){ nextEdge = i->data; nextX = roundOwn(getSmartXForLine(nextEdge, line)); dPrintf(("\tNext edges @ x = %d from %s\n",nextX, fmtColor(nextEdge->owner->color))); } else { dPrintf(("\tNo more edges\n")); nextEdge = NULL; nextX = 0; } nextX = min(nextX, lineWidth); while ((!nextEdge && curPixel < lineWidth) || (curPixel < nextX)) { bool zFight = false, solitary = false; float bestZ = HUGE_VAL; const rb_red_blk_node *node; curDraw = NULL; dPrintf(("\tTesting depth:\n")); for(node = inFlags.tree.first; node != inFlags.tree.sentinel; node = TreeSuccessor((rb_red_blk_tree*)(&inFlags), node)) { const Primitive *prim = node->key; /* We need sub-pixel accuracy */ const float testZ = getZForXY(prim, curPixel, line); if(testZ <= bestZ + PT_EPS){ dPrintf(("\t\tHit: %f <= %f for %s\n",testZ, bestZ, fmtColor(prim->color))); if (CLOSE_ENOUGH(testZ, bestZ)) { if (prim->arity == 1) { zFight = curDraw && curDraw->arity == 1; curDraw = prim; solitary = RBSetContains(&deFlags, prim); } else { zFight = curDraw && curDraw->arity != 1; } } else { zFight = false; bestZ = testZ; curDraw = prim; solitary = RBSetContains(&deFlags, prim); } } else { dPrintf(("\t\tMiss: %f > %f for %s\n",testZ, bestZ, fmtColor(prim->color))); } } if(curDraw){ #ifndef NDEBUG if(nextEdge || solitary){ #endif const int drawWidth = (zFight || solitary) ? 1 : ((nextEdge ? nextX : lineWidth) - curPixel), stopPixel = curPixel + min(lineWidth - curPixel, max(0, drawWidth)); const PaletteRef drawColor = /*(uint16_t)roundOwn(63 * bestZ / 100) << 5;*/decodeColor(curDraw->color); dPrintf(("Drawing %d @ (%d, %d)\n",drawWidth,curPixel,line)); dPrintf(("Drawing %d @ (%d, %d)\n",stopPixel - curPixel,curPixel,line)); while(curPixel < stopPixel){ raster[curPixel++] = drawColor; } #ifndef NDEBUG } else { dPrintf(("Warning: we probably shouldn't have to draw if there are no more edges to turn us off. Look for parity errors\n"); RBTreeClear((rb_red_blk_tree*)&inFlags)); } #endif } else if(!inFlags.tree.size && nextEdge){ /* fast forward, we aren't in any polys */ dPrintf(("Not in any polys at the moment, fast-forwarding(1) to %d\n", nextX)); curPixel = nextX; } else { /* Nothing left */ dPrintf(("Nothing to draw at end of line\n")); curPixel = lineWidth; } for(node = deFlags.first; node != deFlags.sentinel; node = TreeSuccessor(&deFlags, node)){ RBMapRemove(&inFlags, node->key); } RBTreeClear(&deFlags); } if (!inFlags.tree.size && nextEdge) { dPrintf(("Not in any polys at the moment, fast-forwarding(2) to %d\n", nextX)); curPixel = nextX; } } } } #ifndef NDEBUG { dPrintf(("Scanning line: %d\n", line+1)); if(inFlags.tree.size){ rb_red_blk_node *node; dPrintf(("\tGarbage left in inFlags:\n")); for (node = inFlags.tree.first; node != inFlags.tree.sentinel; node = TreeSuccessor((rb_red_blk_tree*)&inFlags, node)) { dPrintf(("\t\t%s\n",fmtColor(((const Primitive*)node->key)->color))); } } } #endif RBTreeClear(&deFlags); RBTreeClear((rb_red_blk_tree*)(&inFlags)); } RBTreeDestroy(&activePrimSet, false); RBTreeDestroy(&deFlags, false); RBTreeDestroy((rb_red_blk_tree*)(&inFlags), false); }
rb_red_blk_tree* teardownBuckets(rb_red_blk_tree* buckets, int numLines){ size_t i; for (i = 0; i < numLines; RBTreeDestroy(buckets + (i++), false)); free(buckets); return NULL; }
int main() { stk_stack* enumResult; int option=0; int newKey,newKey2; int* newInt; rb_red_blk_node* newNode; rb_red_blk_tree* tree; tree=RBTreeCreate(IntComp,IntDest,InfoDest,IntPrint,InfoPrint); while(option!=8) { printf("choose one of the following:\n"); printf("(1) add to tree\n(2) delete from tree\n(3) query\n"); printf("(4) find predecessor\n(5) find sucessor\n(6) enumerate\n"); printf("(7) print tree\n(8) quit\n"); do option=fgetc(stdin); while(-1 != option && isspace(option)); option-='0'; switch(option) { case 1: { printf("type key for new node\n"); scanf("%i",&newKey); newInt=(int*) malloc(sizeof(int)); *newInt=newKey; RBTreeInsert(tree,newInt,0); } break; case 2: { printf("type key of node to remove\n"); scanf("%i",&newKey); if ( ( newNode=RBExactQuery(tree,&newKey ) ) ) RBDelete(tree,newNode);/*assignment*/ else printf("key not found in tree, no action taken\n"); } break; case 3: { printf("type key of node to query for\n"); scanf("%i",&newKey); if ( ( newNode = RBExactQuery(tree,&newKey) ) ) {/*assignment*/ printf("data found in tree at location %i\n",(int)newNode); } else { printf("data not in tree\n"); } } break; case 4: { printf("type key of node to find predecessor of\n"); scanf("%i",&newKey); if ( ( newNode = RBExactQuery(tree,&newKey) ) ) {/*assignment*/ newNode=TreePredecessor(tree,newNode); if(tree->nil == newNode) { printf("there is no predecessor for that node (it is a minimum)\n"); } else { printf("predecessor has key %i\n",*(int*)newNode->key); } } else { printf("data not in tree\n"); } } break; case 5: { printf("type key of node to find successor of\n"); scanf("%i",&newKey); if ( (newNode = RBExactQuery(tree,&newKey) ) ) { newNode=TreeSuccessor(tree,newNode); if(tree->nil == newNode) { printf("there is no successor for that node (it is a maximum)\n"); } else { printf("successor has key %i\n",*(int*)newNode->key); } } else { printf("data not in tree\n"); } } break; case 6: { printf("type low and high keys to see all keys between them\n"); scanf("%i %i",&newKey,&newKey2); enumResult=RBEnumerate(tree,&newKey,&newKey2); while ( (newNode = StackPop(enumResult)) ) { tree->PrintKey(newNode->key); printf("\n"); } free(enumResult); } break; case 7: { RBTreePrint(tree); } break; case 8: { RBTreeDestroy(tree); return 0; } break; default: printf("Invalid input; Please try again.\n"); } } return 0; }