static NODE *remove_r(NODE *r, int x, int *success){ NODE *tmp; int sanity; if(r==NULL){ *success = 0; return NULL; } if(r->val == x){ *success = 1; if(r->left == NULL){ tmp = r->right; free(r); return tmp; } if(r->right == NULL){ tmp = r->left; free(r); return tmp; } // if we get here, r has two children r->val = min_h(r->right); r->right = remove_r(r->right, r->val, &sanity); if(!sanity) printf("ERROR: remove() failed to delete promoted value?\n"); return r; } if(x < r->val){ r->left = remove_r(r->left, x, success); if(r->left != NULL) { // updates min tree vals r->min = r->left->min; } else { r->min = r->val; } } else { r->right = remove_r(r->right, x, success); if(r->right != NULL) { // updates max tree vals r->max = r->right->max; } else { r->max = r->val; } } r->size--; return r; }
void OAC_ReadFileInsertAcList( char *filename) { FILE *fp=NULL; int cnt=0; char buf[512], buf1[256]; if( (fp=fopen( filename, "r")) == NULL ) return; while( fgets( buf, sizeof(buf)-1, fp) ){ if( buf[0] == '#' || buf[0] == '\n' || buf[0] == 0 ) continue; remove_r( buf ); easyGetTokenFromBuf( buf, ':', 1, buf1, sizeof( buf1)); sprintf( OAC_List[cnt].name, "%s", buf1); easyGetTokenFromBuf( buf, ':', 2, buf1, sizeof( buf1)); sprintf( OAC_List[cnt].addr, "%s", buf1); OAC_List[cnt].use = 1; cnt++; if( cnt >= MAXTCPCONNECTION ) break; } fclose( fp); {//andy_log int i; for( i=0; i<MAXTCPCONNECTION; i++){ if( OAC_List[i].use == 0 ) continue; log( "OAC_List[%d] %s %s .\n", i, OAC_List[i].name, OAC_List[i].addr) } } }
// remove node with val x from tree int bst_remove(BST_PTR t, int x){ int success; t->root = remove_r(t->root, x, &success); return success; }
static void workerMainLoop( void ) { char linebuf[4096]; int i_flag;//Arminitus && ttom 12/15 time_t retime; #ifndef _FIX_WORKS struct sockaddr_in sin; int addrlen = sizeof( sin ); FILE *fp; int newsockfd ; while(1){ fd_set rfds; struct timeval t; t.tv_sec = timeout; t.tv_usec = 0; FD_ZERO( &rfds ); FD_SET( mainsockfd , &rfds ); select( 1024 , &rfds , (fd_set*) NULL , (fd_set*)NULL , &t ); if( FD_ISSET( mainsockfd , &rfds ) ){ newsockfd = accept( mainsockfd , (struct sockaddr*) &sin , &addrlen ); if( newsockfd < 0 ){ fprintf( stderr,"accept error! \n"); } else { memcpy(&myIP, &sin.sin_addr, sizeof(long)); fprintf( stderr,"accepted. myIP=%ld\n", myIP ); } break; } else { fprintf(stderr, "accept timed out." ); exit(0); } } close(mainsockfd); { int flag = 1; int result = setsockopt( newsockfd, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int)); if( result != 0 ){ fprintf( stderr , "nodelay error!\n" ); } } fp = fdopen( newsockfd , "r+"); if( fp == NULL ){ fprintf( stderr,"fdopen error.abort" ); return ; } #endif //確認CS可連線 if( checkCSconnect() == -1 ) return; #ifdef _FIX_WORKS if( !LoginToAC() ) //login to ac return; retime = time( NULL); while( WORK_TYPE!=-1) { #else while( fgets( linebuf,sizeof(linebuf), fp)){ #endif // Spock 2000/10/31 char id[104] ,pas[1024] , flag[8] , process[16]; // Spock end int knret; char deadline[100] = "0"; // _TIMEOUTKICK usleep(10*1000); #ifdef _FIX_WORKS if( (WORK_TYPE = Ac_message_accept( linebuf, sizeof( linebuf))) <= 0 ) continue; retime = time( NULL); #endif memset( id, 0, sizeof( id)); memset( process, 0, sizeof( process)); memset( flag, 0, sizeof( flag)); /* chop */ linebuf[strlen(linebuf)-1]=0; /* kill-\r */ remove_r( linebuf ); easyGetTokenFromString( linebuf , 1 , id , sizeof( id )); easyGetTokenFromString( linebuf , 2 , pas , sizeof( pas )); // Nuke +1 easyGetTokenFromString( linebuf , 3 , flag, sizeof(flag)); // Spock 2000/10/31 easyGetTokenFromString( linebuf , 4 , process , sizeof(process) ); // Spock end // Nuke i_flag=0; //Arminius && ttom i_flag=atoi(flag); //Arminius && ttom if((!process)||(!*process)){ knret=-7; }else{ switch (i_flag) { //Arminius && ttom #ifdef _FIX_MESSAGE // WON ADD 修改封包內容 #ifdef _TIMEOUTKICK case 1: // List #ifdef _AP_CHECK_3_TIMES // WON ADD 減少認證次數 knret = 0; #else knret = doKN( id, pas, flag, "", deadline); #endif break; case 4: // Delete knret = doKN( id , pas , flag, "" , deadline); break; case 2: // Load knret = doKN( id , pas , flag, "" , deadline); break; case 3: // Save knret = doKN( id , pas, flag, "" , deadline); break; case 5: // recheck WGS knret = doKN( id , pas , flag, "" , deadline); break; #else case 1: // List #ifdef _AP_CHECK_3_TIMES // WON ADD 減少認證次數 knret = 0; #else knret = doKN( id, pas, flag, ""); #endif break; case 4: // Delete knret = doKN( id , pas , flag, "" ); break; case 2: // Load knret = doKN( id , pas , flag, "" ); break; case 3: // Save knret = doKN( id , pas, flag, "" ); break; #endif #else case 1: // List knret = doKN( id, pas, flag, ""); break; case 4: // Delete knret = doKN( id , pas , flag , "" ); break; case 2: // Load knret = doKN( id , pas , flag , process ); break; case 3: // Save knret = doKN( id , pas , flag , process ); break; #endif default: knret = -7; } } #ifdef _FIX_WORKS {//andy_add int ret; char buf1[256]; #ifdef _TIMEOUTKICK sprintf( buf1, "%d %s \n", knret, deadline); #else sprintf( buf1, "%d\n", knret); #endif Log( buf1); if((ret = write( afd, buf1, sizeof( buf1))) < 0 ) { close( afd); afd = 0; break; } } memset( linebuf, 0, sizeof( linebuf)); #else #ifdef _TIMEOUTKICK fprintf( fp , "%d %s \n", knret, deadline ); #else fprintf( fp , "%d\n", knret ); #endif #endif } #ifdef _FIX_WORKS if( afd > 0 ) close( afd); if( csd > 0 ) close( csd); #else fclose( fp ); #endif //if( AcLogFile != NULL) // fclose( AcLogFile); Log( "acsv closed the connection. aborting.\n" ); } static void parseOpt( int argc , char **argv ) { int c; int option_index; #ifdef _ADD_AC_IP // WON ADD 修改封包內容 memset( AC_IP, -1 , sizeof( AC_IP) ); #endif if( argc == 1 ){ fprintf( stderr , "Argument error: print usage by acwk -h\n" ); exit(0); } while(1){ static struct option long_options[] = { {"port" , 1, 0 ,'p'}, {"debug" , 1, 0 , 'd'}, {"help" , 0 , 0 , 'h'}, {"logdir", 1, 0, 'l' }, {"csaddr", 1, 0, 'a' }, {"csport", 1, 0, 'c' }, #ifdef _ADD_AC_IP // WON ADD 修改封包內容 {"acaddr", 1, 0, 'w' }, #endif {0,0,0,0} }; #ifdef _FIX_MESSAGE // WON ADD 修改封包內容 c = getopt_long ( argc, argv, "p:dhl:a:c:w:", long_options, &option_index ); #else c = getopt_long ( argc, argv, "p:dhl:a:c:", long_options, &option_index ); #endif if( c == -1 )break; switch(c ){ case 'l': if( optarg){ snprintf( logdir, sizeof( logdir), "%s", optarg ); } else{ fprintf( stderr , "need directory name after -l.\n" ); } break; case 'p' : port = atoi( optarg ); break; case 'd': debug = 1; break; case 'h': fprintf( stderr, "Usage: acwk [-d|--debug] [-p port|--port port] [-h|--help] [-l logdir]\n" " [-a CSAddress] [-c CSPort]\n" "Default debug mode is 0.\n" "\nCopyright 1999 Kengo Nakajima / Japan system supply\n" ); exit(0); break; // Spock 2000/12/5 case 'a': strcpy( WGSAddress, optarg ); break; case 'c': WGSPort = atoi( optarg ); break; // Spock end #ifdef _ADD_AC_IP // WON ADD 加AC_IP至通訊協定中 case 'w': strcpy( AC_IP, optarg ); Log( AC_IP ); break; #endif } } }
//Remove a node, recursive version //NOTE: Since removing a node can rebalance the tree, ensure that NO processing occurs // after any recursive call. node* remove_r(Key key, node* parent, node* curr) { //Base case: Not found if (!curr) { return nullptr; } //Base case: Node found if (curr->key==key) { //Obtain a reference to this parent's pointer (left or right) that points to this object. node*& parentPtr = !parent?root:parent->left==curr?parent->left:parent->right; //Three posibilities (I tried generalizing them, but it took up more code). if (!curr->left && !curr->right) { //Simple case: We are deleting a node with no children; just delete it and set // its parent pointer to null. parentPtr = nullptr; delete curr; } else if (!curr->left || !curr->right) { //Simple case 2: Only one child. Delete this node, and have the parent point to // this child. parentPtr = curr->left?curr->left:curr->right; delete curr; } else { //Slightly more complex case: find the previous in-order node and copy // its contens here... then delete THAT node. node* toDelete = find_and_slice_child(curr, curr->left); curr->data = toDelete->data; curr->key = toDelete->key; delete toDelete; } //Update size realSize--; //Check if rebalancing is necessary if (autoBalance && realSize>=minRebalanceSize) { bool outOfBalance = false; if (!rigidDelete) { //Check if our size is less than half the max size (alpha modifies this slightly) outOfBalance = realSize < (alpha*maxSize)/1000; } else { //Check if the size is one less than an exact power of two outOfBalance = !(realSize&(realSize+1)); } //If so, rebalance at the root and reset maxSize if (outOfBalance) { rebalance(nullptr, root, realSize); } } //Return null return nullptr; } //Recursive case if (key<curr->key) { return remove_r(key, curr, curr->left); } else { return remove_r(key, curr, curr->right); } }
void remove(Key key) { remove_r(key, nullptr, root); }