void put_in_output_queue(char *stuff) { output_queue = append_and_free_old(output_queue, stuff); DPRINTF3(DEBUG_TERMIO,"put %d bytes in output queue (which now has %d bytes): %s", (int) strlen(stuff), (int) strlen(output_queue), mangle_string_for_debug_log(stuff, 20)); }
char *pass_through_filter(int tag, const char *buffer) { char *filtered; DPRINTF3(DEBUG_FILTERING, "to filter (%s, %d bytes) %s", tag2description(tag), (int) strlen(buffer), mangle_string_for_debug_log(buffer, MANGLE_LENGTH)); if (filter_pid ==0) return mysavestring(buffer); write_to_filter((expected_tag = tag), buffer); filtered = read_from_filter(tag); DPRINTF2(DEBUG_FILTERING, "from filter (%d bytes) %s", (int) strlen(filtered), mangle_string_for_debug_log(filtered, MANGLE_LENGTH)); return filtered; }
void deleteSymDef(void *p) { S_symbol *pp; S_javaStat *scp; pp = (S_symbol *) p; DPRINTF3("deleting %s %s\n", pp->name, pp->linkName); if (symTabDelete(s_javaStat->locals,pp)) return; if (symTabDelete(s_symTab,pp)==0) { assert(s_opt.taskRegime); if (s_opt.taskRegime != RegimeEditServer) { error(ERR_INTERNAL,"symbol on deletion not found"); } } }
void mysignal(int sig, sighandler_type handler) { #ifdef HAVE_SIGACTION struct sigaction action; DPRINTF3(DEBUG_SIGNALS,"Setting handler for signal %d (%s) to <0x%lx>", sig, signal_name(sig), (long) handler); action.sa_handler = handler; sigfillset(&action.sa_mask); /* don't bother making our signal handlers re-entrant (they aren't) */ action.sa_flags = (sig == SIGCHLD ? SA_NOCLDSTOP : 0); /* no SA_RESTART */ if (sigaction(sig, &action, NULL) != 0) # else /* rlwrap running in Ye Olde Computer Museum?? */ if (signal(sig, handler) == SIG_ERR) # endif if(handler != SIG_DFL) /* allow e.g. KILL to be set to its default */ myerror(FATAL|USE_ERRNO, "Failed setting handler for signal %d (%s)", sig, signal_name(sig)); }
void flush_output_queue() { int nwritten, queuelen, how_much; char *old_queue = output_queue; char *nl; if (!output_queue) return; queuelen = strlen(output_queue); nl = strchr(output_queue, '\n'); how_much = min(BUFFSIZE, nl ? 1+ nl - output_queue : queuelen); /* never write more than one line, and never more than BUFFSIZE in one go */ nwritten = write(master_pty_fd, output_queue, how_much); assert(nwritten <= strlen(output_queue)); if (debug) { char scratch = output_queue[nwritten]; output_queue[nwritten] = '\0'; /* temporarily replace the last written byte + 1 by a '\0' */ DPRINTF3(DEBUG_TERMIO,"flushed %d of %d bytes from output queue to pty: %s", nwritten, queuelen, mangle_string_for_debug_log(output_queue, MANGLE_LENGTH)); output_queue[nwritten] = scratch; } if (nwritten < 0) { switch (nwritten) { case EINTR: case EAGAIN: return; default: myerror("write to master pty failed"); } } if (!output_queue[nwritten]) /* nothing left in queue */ output_queue = NULL; else output_queue = mysavestring(output_queue + nwritten); /* this much is left to be written */ free(old_queue); }
static void pass_on_signal(int signo) { int ret, saved_errno = errno, pass_it_on = TRUE; DEBUG_RANDOM_SLEEP; zero_select_timeout(); #ifdef DEBUG log_named_signal(signo); #endif if(pass_on_sigINT_as_sigTERM && signo == SIGINT) signo=SIGTERM; switch (signo) { case SIGWINCH: /* non-POSIX, but present on most systems */ /* Make slave pty's winsize equal to that of STDIN. Pass the signal on *only if* winsize has changed. This is particularly important because we have the slave pty still open - when we pass on the signal the child will probably do a TIOCSWINSZ ioctl() on the slave pty - causing us (the parent) to get a SIGWINCH again, thus getting stuck in a loop */ pass_it_on = adapt_tty_winsize(STDIN_FILENO, master_pty_fd); break; case SIGTERM: sigterm_received = TRUE; break; default: break; } if (!command_pid) pass_it_on = FALSE; /* no child (yet) to pass it on to */ if (pass_it_on) { /* we resend the signal to the process *group* of the child */ ret = kill( -command_pid, signo); DPRINTF3(DEBUG_SIGNALS, "kill(%d,%s) = %d", -command_pid, signal_name(signo), ret); we_just_got_a_signal_or_EOF = TRUE; /* signal to main loop that next command output should leave the prompt alone */ } errno = saved_errno; }
static int handle_hotkey2(int UNUSED(count), int hotkey, int ignore_history) { char *prefix, *postfix, *history, *histpos_as_string, *executing_keyseq; char *new_prefix, *new_postfix, *new_history, *new_histpos_as_string, *message; char *filter_food, *filtered, **fragments, *new_rl_line_buffer; int length, new_histpos; unsigned long int hash; static const unsigned int MAX_HISTPOS_DIGITS = 6; /* one million history items should suffice */ #ifdef HAVE_RL_EXECUTING_KEYSEQ /* i.e. if readline version is >= 6.3 */ executing_keyseq = mysavestring(rl_executing_keyseq); #else executing_keyseq = mysavestring("?"); *executing_keyseq = hotkey; /* The filter will only get the *last* byte of the key sequence that triggered rl_handle_hotkey */ #endif DPRINTF3(DEBUG_READLINE, "hotkey press (ignore_history == %d): %x (%s)", ignore_history, hotkey, mangle_string_for_debug_log(executing_keyseq, MANGLE_LENGTH)); if (hotkey == '\t') /* this would go horribly wrong with all the splitting on '\t' going on.... @@@ or pass key as a string e.g. "009" */ myerror(FATAL | NOERRNO, "Sorry, you cannot use TAB as an hotkey in rlwrap"); prefix = mysavestring(rl_line_buffer); prefix[rl_point] = '\0'; /* chop off just before cursor */ postfix = mysavestring(rl_line_buffer + rl_point); if (ignore_history) { histpos_as_string = mysavestring("0"); history = mysavestring(""); } else { histpos_as_string = as_string(where_history()); assert(strlen(histpos_as_string) <= MAX_HISTPOS_DIGITS); history = entire_history_as_one_string(); hash = hash_multiple(2, history, histpos_as_string); } /* filter_food = key + tab + prefix + tab + postfix + tab + history + tab + histpos + '\0' */ length = strlen(rl_line_buffer) + strlen(history) + MAX_HISTPOS_DIGITS + 5; filter_food = mymalloc(length); sprintf(filter_food, "%s\t%s\t%s\t%s\t%s", executing_keyseq, prefix, postfix, history, histpos_as_string); /* this is the format that the filter expects */ /* let the filter filter ...! */ filtered= pass_through_filter(TAG_HOTKEY, filter_food); /* OK, we now have to read back everything. There should be exactly 5 TAB-separated components*/ fragments = split_on_single_char(filtered, '\t', 5); message = fragments[0]; new_prefix = fragments[1]; new_postfix = fragments[2]; new_history = fragments[3]; new_histpos_as_string = fragments[4]; if (!ignore_history && hash_multiple(2, new_history, new_histpos_as_string) != hash) { /* history has been rewritten */ char **linep, **history_lines = split_on_single_char(new_history, '\n', 0); DPRINTF3(DEBUG_READLINE, "hash=%lx, new_history is %d bytes long, histpos <%s>", hash, (int) strlen(new_history), new_histpos_as_string); clear_history(); for (linep = history_lines; *linep; linep++) add_history(*linep); new_histpos = my_atoi(new_histpos_as_string); history_set_pos(new_histpos); free_splitlist(history_lines); } new_rl_line_buffer = add2strings(new_prefix, new_postfix); if ( (length = strlen(new_rl_line_buffer)) > 0 && new_rl_line_buffer[length - 1] == '\n') { new_rl_line_buffer[length - 1] = '\0'; rl_done = TRUE; return_key = (char) '\n'; assert(strchr(new_rl_line_buffer, '\n') == NULL); } rl_delete_text(0, strlen(rl_line_buffer)); rl_point = 0; rl_insert_text(new_rl_line_buffer); rl_point = strlen(new_rl_line_buffer); if (*message && *message != hotkey) { /* if message has been set (i.e. != hotkey) , and isn't empty: */ message = append_and_free_old(mysavestring(message), " "); /* put space (for readability) between the message and the input line .. */ message_in_echo_area(message); /* .. then write it to echo area */ } clear_line(); rl_on_new_line(); rl_redisplay(); free_splitlist(fragments); /* this will free all the fragments (and the list itself) in one go */ free_multiple(prefix, postfix, filter_food, executing_keyseq, filtered, new_rl_line_buffer, history, histpos_as_string, FMEND); return 0; }
static void my_homegrown_redisplay(int hide_passwords) { static int line_start = 0; /* at which position of prompt_plus_line does the printed line start? */ static int line_extends_right = 0; static int line_extends_left = 0; static char *previous_line = NULL; int width = winsize.ws_col; int skip = max(1, min(width / 5, 10)); /* jumpscroll this many positions when cursor reaches edge of terminal */ char *prompt_without_ignore_markers; int colourless_promptlen = colourless_strlen(rl_prompt, &prompt_without_ignore_markers,0); int promptlen = strlen(prompt_without_ignore_markers); int invisible_chars_in_prompt = promptlen - colourless_promptlen; char *prompt_plus_line = add2strings(prompt_without_ignore_markers, rl_line_buffer); char *new_line; int total_length = strlen(prompt_plus_line); int curpos = promptlen + rl_point; /* cursor position within prompt_plus_line */ int i, printed_length, new_curpos, /* cursor position on screen */ keep_old_line, vlinestart, printwidth, last_column; DPRINTF3(DEBUG_AD_HOC,"rl_prompt: <%s>, prompt_without_ignore_markers: <%s>, prompt_plus_line: <%s>", rl_prompt, prompt_without_ignore_markers, prompt_plus_line); /* In order to handle prompt with colour we either print the whole prompt, or start past it: starting in the middle is too difficult (i.e. I am too lazy) to get it right. We use a "virtual line start" vlinestart, which is the number of invisible chars in prompt in the former case, or linestart in the latter (which then must be >= strlen(prompt)) At all times (before redisplay and after) the following is true: - the cursor is at column (curpos - vlinestart) (may be < 0 or > width) - the character under the cursor is prompt_plus_line[curpos] - the character at column 0 is prompt_plus_line[linestart] - the last column is at <number of printed visible or invisible chars> - vlinestart the goal of this function is to display (part of) prompt_plus_line such that the cursor is visible again */ if (hide_passwords) for (i = promptlen; i < total_length; i++) prompt_plus_line[i] = '*'; /* hide a pasword by making user input unreadable */ if (rl_point == 0) /* (re)set at program start and after accept_line (where rl_point is zeroed) */ line_start = 0; assert(line_start == 0 || line_start >= promptlen); /* the line *never* starts in the middle of the prompt (too complicated to handle)*/ vlinestart = (line_start > promptlen ? line_start : invisible_chars_in_prompt); if (curpos - vlinestart > width - line_extends_right) /* cursor falls off right edge ? */ vlinestart = (curpos - width + line_extends_right) + skip; /* jumpscroll left */ else if (curpos < vlinestart + line_extends_left) { /* cursor falls off left edge ? */ if (curpos == total_length) /* .. but still at end of line? */ vlinestart = max(0, total_length - width); /* .. try to display entire line */ else /* in not at end of line .. */ vlinestart = curpos - line_extends_left - skip; /* ... jumpscroll right .. */ } if (vlinestart <= invisible_chars_in_prompt) { line_start = 0; /* ... but not past start of line! */ vlinestart = invisible_chars_in_prompt; } else if (vlinestart > invisible_chars_in_prompt && vlinestart <= promptlen) { line_start = vlinestart = promptlen; } else { line_start = vlinestart; } printwidth = (line_start > 0 ? width : width + invisible_chars_in_prompt); printed_length = min(printwidth, total_length - line_start); /* never print more than width */ last_column = printed_length - vlinestart; /* some invariants : 0 <= line_start <= curpos <= line_start + printed_length <= total_length */ /* these are interesting: ^ ^ */ assert(0 <= line_start); assert(line_start <= curpos); assert(curpos <= line_start + printed_length); /* <=, rather than <, as cursor may be past eol */ assert(line_start + printed_length <= total_length); new_line = prompt_plus_line + line_start; new_line[printed_length] = '\0'; new_curpos = curpos - vlinestart; /* indicate whether line extends past right or left edge (i.e. whether the "interesting inequalities marked ^ above are really unequal) */ line_extends_left = (line_start > 0 ? 1 : 0); line_extends_right = (total_length - vlinestart > width ? 1 : 0); if (line_extends_left) new_line[0] = '<'; if (line_extends_right) new_line[printwidth - 1] = '>'; keep_old_line = FALSE; if (term_cursor_hpos) { if (previous_line && strcmp(new_line, previous_line) == 0) { keep_old_line = TRUE; } else { if (previous_line) free(previous_line); previous_line = mysavestring(new_line); } } /* DPRINTF2(DEBUG_AD_HOC, "keep_old_line=%d, new_line=<%s>", keep_old_line, new_line); */ /* keep_old_line = TRUE; */ if (!keep_old_line) { clear_line(); cr(); write_patiently(STDOUT_FILENO, new_line, printed_length, "to stdout"); } assert(term_cursor_hpos || !keep_old_line); /* if we cannot position cursor, we must have reprinted ... */ if (term_cursor_hpos) cursor_hpos(new_curpos); else /* ... so we know we're 1 past last position on line */ backspace(last_column - new_curpos); free(prompt_plus_line); free(prompt_without_ignore_markers); }
static int is_server_running(rmedia_handle_t *handle) { door_arg_t door_args; smedia_reqping_t reqping; smedia_retping_t *retping; int ret_val; int door_fd; CLIENT *clnt; char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)]; smserver_info *server_info; /* * We will assume that we are running at level 2 or greater * and attempt to contact the server using RPC mecahnisms. * If that fails then we will attempt to contact the server * using non-rpc mechanism. This will enable the libsmedia * to be used in SINGLE user mode when inetd is not running. * We expect the server to have been started manually by user. * * Note that "localhost" is used (vs hostname (eg, "uname -n")), * as this minimizes interference with common IPSec rules. */ clnt = clnt_create("localhost", SMSERVERPROG, SMSERVERVERS, "circuit_v"); if (clnt == (CLIENT *)NULL) { /* * The failure could be that we are running at level 1 */ door_fd = open(smedia_service, O_RDONLY, 0644); if (door_fd < 0) { DPRINTF1("Error in opening %s\n", smedia_service); return (0); } DPRINTF1("rbuf address=%p\n", rbuf); reqping.cnum = SMEDIA_CNUM_PING; door_args.data_ptr = (char *)&reqping; door_args.data_size = sizeof (smedia_services_t); door_args.desc_ptr = NULL; door_args.desc_num = 0; door_args.rbuf = rbuf; door_args.rsize = sizeof (rbuf); ret_val = door_call(door_fd, &door_args); (void) close(door_fd); if (ret_val < 0) { return (0); } DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", door_args.rsize, door_args.data_size, door_args.data_ptr); retping = (smedia_retping_t *)( (void *)door_args.data_ptr); if (retping->cnum != SMEDIA_CNUM_PING) { DPRINTF1("*** door call failed *** cnum " "returned = 0x%x\n", retping->cnum); return (0); } return (1); } server_info = smserverproc_get_serverinfo_1(NULL, clnt); if (server_info == NULL) { if (clnt) clnt_destroy(clnt); return (0); } if (server_info->status != 0) { if (clnt) clnt_destroy(clnt); DPRINTF1("get server_info call failed. " "status = %d\n", server_info->status); return (0); } if (server_info->vernum != SMSERVERVERS) { if (clnt) clnt_destroy(clnt); DPRINTF2("version expected = %d version " "returned = %d\n", SMSERVERVERS, server_info->vernum); return (0); } door_fd = open(smedia_service, O_RDONLY, 0644); if (door_fd < 0) { DPRINTF1("Error in opening %s\n", smedia_service); return (0); } DPRINTF1("rbuf address=%p\n", rbuf); reqping.cnum = SMEDIA_CNUM_PING; door_args.data_ptr = (char *)&reqping; door_args.data_size = sizeof (smedia_services_t); door_args.desc_ptr = NULL; door_args.desc_num = 0; door_args.rbuf = rbuf; door_args.rsize = sizeof (rbuf); ret_val = door_call(door_fd, &door_args); (void) close(door_fd); if (ret_val < 0) { return (0); } DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", door_args.rsize, door_args.data_size, door_args.data_ptr); retping = (smedia_retping_t *)((void *)door_args.data_ptr); if (retping->cnum != SMEDIA_CNUM_PING) { DPRINTF1("*** door call failed *** cnum returned " "= 0x%x\n", retping->cnum); return (0); } handle->sm_clnt = clnt; return (1); }
smedia_handle_t get_handle_from_fd(int32_t fd) { rmedia_handle_t *handle; void *lib_handle; int door_fd, door_server; int ret_val; door_arg_t door_args; smedia_reqopen_t reqopen; smedia_reterror_t *reterror; door_desc_t ddesc[2]; char rbuf[sizeof (smedia_services_t) + sizeof (door_desc_t)]; struct stat stat; DPRINTF("smedia_get_handle called\n"); handle = (rmedia_handle_t *)malloc(sizeof (rmedia_handle_t)); if (handle == NULL) { DPRINTF("Could not allocate memory for handle\n"); return (NULL); } (void) memset((void *) handle, 0, sizeof (rmedia_handle_t)); handle->sm_fd = -1; handle->sm_door = -1; handle->sm_death_door = -1; handle->sm_buffd = -1; handle->sm_buf = NULL; handle->sm_bufsize = 0; if (ioctl(fd, DKIOCINFO, &handle->sm_dkinfo) == -1) { free(handle); PERROR("DKIOCINFO failed"); return (NULL); } lib_handle = get_dev_library_handle(fd); if (lib_handle == NULL) { free(handle); DPRINTF("lib_Handle is NULL\n"); errno = ENOTSUP; return (NULL); } DPRINTF("Handle initialised successfully.\n"); /* Initialise the handle elements */ handle->sm_lib_handle = lib_handle; handle->sm_signature = LIBSMEDIA_SIGNATURE; DPRINTF2("fd=%d signature=0x%x\n", handle->sm_fd, handle->sm_signature); if ((handle->sm_dkinfo.dki_ctype == DKC_SCSI_CCS) || (handle->sm_dkinfo.dki_ctype == DKC_MD21) || (handle->sm_dkinfo.dki_ctype == DKC_CDROM)) { ret_val = is_server_running(handle); if (ret_val == 0) { (void) dlclose(handle->sm_lib_handle); free(handle); return (NULL); } door_fd = open(smedia_service, O_RDONLY, 0644); if (door_fd < 0) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); DPRINTF1("Error in opening %s\n", smedia_service); PERROR(smedia_service); return (NULL); } DPRINTF1("rbuf address=%p\n", rbuf); ddesc[0].d_data.d_desc.d_descriptor = fd; ddesc[0].d_attributes = DOOR_DESCRIPTOR; reqopen.cnum = SMEDIA_CNUM_OPEN_FD; door_args.data_ptr = (char *)&reqopen; door_args.data_size = sizeof (smedia_services_t); door_args.desc_ptr = &ddesc[0]; door_args.desc_num = 1; door_args.rbuf = rbuf; door_args.rsize = sizeof (rbuf); ret_val = door_call(door_fd, &door_args); (void) close(door_fd); if (ret_val < 0) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); PERROR("door_call"); return (NULL); } DPRINTF3("rsize = %d data_size = %d data_ptr = %p \n", door_args.rsize, door_args.data_size, door_args.data_ptr); reterror = (smedia_reterror_t *)((void *)door_args.data_ptr); if (reterror->cnum != SMEDIA_CNUM_OPEN_FD) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); DPRINTF1( "*** door call failed *** cnum returned = 0x%x\n", reterror->cnum); errno = reterror->errnum; return (NULL); } /* * 2 door descriptors are returned after the above door call. * The first door descriptor is the one that will be used * in subsequent smedia calls. A dedicated thread is * associated with this door to handle client calls. * The second door descriptor is needed to signal unexpected * death of the client to the server. This will help the server * to do the necessary cleanup. */ if (door_args.desc_num != 2) { (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); DPRINTF("Num of door descriptors returned by " "server is not 2"); if (door_args.desc_num) (void) close(door_args.desc_ptr->\ d_data.d_desc.d_descriptor); return (NULL); } door_server = door_args.desc_ptr->d_data.d_desc.d_descriptor; /* Check if the descriptor returned is S_IFDOOR */ if (fstat(door_server, &stat) < 0) { PERROR("fstat"); (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); return (NULL); } if (!S_ISDOOR(stat.st_mode)) { DPRINTF( "Descriptor returned by door_call is not of type DOOR\n"); (void) dlclose(handle->sm_lib_handle); free(handle); if (handle->sm_clnt) clnt_destroy(handle->sm_clnt); return (NULL); } handle->sm_door = door_server; handle->sm_fd = fd; door_args.desc_ptr++; handle->sm_death_door = door_args.desc_ptr->d_data.d_desc.d_descriptor; DPRINTF("door call succeeded.\n"); return ((smedia_handle_t)handle); } else { handle->sm_fd = fd; return ((smedia_handle_t)handle); } }
/* Given the actual data set <dataSet>, estimates the values for algorithm parameters that would give the optimal running time of a query. The set <sampleQueries> is a set with query sample points (R-NN DS's parameters are optimized for query points from the set <sampleQueries>). <sampleQueries> could be a sample of points from the actual query set or from the data set. When computing the estimated number of collisions of a sample query point <q> with the data set points, if there is a point in the data set with the same pointer with <q> (that is when <q> is a data set point), then the corresponding point (<q>) is not considered in the data set (for the purpose of computing the respective #collisions estimation). //如果查询样本点来自数据集,则为了考虑碰撞估计,不讲对应的样本查询点考虑进数据集合 The return value is the estimate of the optimal parameters. */ RNNParametersT computeOptimalParameters(RealT R, //半径 RealT successProbability, //成功率 IntT nPoints, //数据点的个数 IntT dimension, //维度 PPointT *dataSet, //数据集合 IntT nSampleQueries, //样本查询点的个数 PPointT *sampleQueries, //样本查询点的数据集 MemVarT memoryUpperBound){ //每个半径需要使用内存的上界,多个半径的时候Qboundry才会使用到,用一个半径的时候,是使用不到的。 ASSERT(nSampleQueries > 0); initializeLSHGlobal(); //设置了一个时间参数,把时间函数所花的时间求出来,得出精确操作所花费的时间 //用来评估算法效率 RNNParametersT optParameters; optParameters.successProbability = successProbability; optParameters.dimension = dimension; optParameters.parameterR = R; #ifdef USE_L1_DISTANCE optParameters.parameterR2 = R; //L1 norm下R2 与R相等, //R与R2的作用? #else optParameters.parameterR2 = SQR(R); //?R2的作用是什么 #endif optParameters.useUfunctions = TRUE; // TODO: could optimize here: // maybe sometimes, the old way // was better. optParameters.parameterW = PARAMETER_W_DEFAULT; //W用于计算L2 norm下的LSH函数的参数,4 optParameters.parameterT = nPoints; //数据点的个数 optParameters.typeHT = HT_HYBRID_CHAINS; //hashing表构建的类型 // Compute the run-time parameters (timings of different parts of the algorithm). IntT nReps = 10; // # number of repetitiions //重复的数量为10个 RealT lshPrecomp = 0, uhashOver = 0, distComp = 0; //LSH预处理的时间,从Hash表中取得桶的时间 ,计算两点距离的时间 for(IntT i = 0; i < nReps; i++){ //重复nReps次,计算LSH 3个阶段的时间,然后在计算出来的平均时间。 RealT lP, uO, dC; //并且进行了哈希表的构建,哈希函数的计算,等等 determineRTCoefficients(optParameters.parameterR, optParameters.successProbability, optParameters.useUfunctions, optParameters.typeHT, optParameters.dimension, nPoints, dataSet, lP, uO, dC); lshPrecomp += lP; //累计重复nReps次的时间。 因为随机数产生是不同的,所以每次处理的时间也不同 uhashOver += uO; distComp += dC; DPRINTF4("Coefs: lP = %0.9lf\tuO = %0.9lf\tdC = %0.9lf\n", lP, uO, dC); } lshPrecomp /= nReps; //平均处理的时间 uhashOver /= nReps; distComp /= nReps; DPRINTF("Coefs (final): lshPrecomp = %0.9lf\n", lshPrecomp); DPRINTF("Coefs (final): uhashOver = %0.9lf\n", uhashOver); DPRINTF("Coefs (final): distComp = %0.9lf\n", distComp); DPRINTF("Remaining memory: %lld\n", memoryUpperBound); // Try all possible <k>s and choose the one for which the time // estimate of a query is minimal. IntT k; RealT timeLSH, timeUH, timeCycling; //IntT queryIndex = genRandomInt(0, nPoints); //PPointT query = dataSet[queryIndex]; // query points = a random points from the data set. //查询点取为从数据集中取的随机点 IntT bestK = 0; RealT bestTime = 0; for(k = 2; ; k += 2){ //之前进行计算的时候,将k预设为16 DPRINTF("ST. k = %d\n", k); IntT m = computeMForULSH(k, successProbability); //通过k和p计算出m IntT L = m * (m-1) / 2; //DPRINTF("Available memory: %lld\n", getAvailableMemory()); if (L * nPoints > memoryUpperBound / 12){ //??为什么除以12呢?? 12是一个常数,用于对内存的估算 //4×tableSize+8×#buckets+8n<20n break; } timeLSH = m * k * lshPrecomp; //m次,k维预处理时间,之前有计算好平均每次处理的时间 timeUH = L * uhashOver; //L个hash表 //RealT nCollisions = estimateNCollisionsFromDSPoint(nPoints, dimension, dataSet, queryIndex, k, L, R); // Compute the mean number of collisions for the points from the sample query set. RealT nCollisions = 0; //计算平均冲突的点的数量 for(IntT i = 0; i < nSampleQueries; i++){ nCollisions += estimateNDistinctCollisions(nPoints, dimension, dataSet, sampleQueries[i], TRUE, k, m, R); } nCollisions /= nSampleQueries; //每个查询点能查询到近邻点的平均数量 timeCycling = nCollisions * distComp; //查询点查到所有近邻的时间?? DPRINTF3("ST.m=%d L=%d \n", m, L); DPRINTF("ST.Estimated # distinct collisions = %0.6lf\n", (double)nCollisions); DPRINTF("ST.TimeLSH = %0.6lf\n", timeLSH); DPRINTF("ST.TimeUH = %0.6lf\n", timeUH); DPRINTF("ST.TimeCycling = %0.6lf\n", timeCycling); DPRINTF("ST.Sum = %0.6lf\n", timeLSH + timeUH + timeCycling); if (bestK == 0 || (timeLSH + timeUH + timeCycling) < bestTime) { //第一轮循环k=0,此时bestTime是比较大的,所以随着k的增大,得到最优时间 bestK = k; bestTime = timeLSH + timeUH + timeCycling; } ASSERT(k < 100); // otherwise, k reached 100 -- which, from // experience, should never happen for reasonable // data set & available memory amount. } DPRINTF("STO.Optimal k = %d\n", bestK); IntT m = computeMForULSH(bestK, successProbability); //计算L2 norm下的m IntT L = m * (m-1) / 2; timeLSH = m * bestK * lshPrecomp; timeUH = L * uhashOver; // Compute the mean number of collisions for the points from the sample query set. RealT nCollisions = 0; for(IntT i = 0; i < nSampleQueries; i++){ nCollisions += estimateNDistinctCollisions(nPoints, dimension, dataSet, sampleQueries[i], TRUE, k, m, R); } nCollisions /= nSampleQueries; // timeCycling = estimateNCollisionsFromDSPoint(nPoints, dimension, dataSet, queryIndex, bestK, L, R) * distComp; timeCycling = nCollisions * distComp; DPRINTF("STO.TimeLSH = %0.6lf\n", timeLSH); DPRINTF("STO.TimeUH = %0.6lf\n", timeUH); DPRINTF("STO.TimeCycling = %0.6lf\n", timeCycling); DPRINTF("STO.Sum = %0.6lf\n", timeLSH + timeUH + timeCycling); optParameters.parameterK = bestK; optParameters.parameterM = m; optParameters.parameterL = L; return optParameters; }
/* Read history and completion word lists */ void init_rlwrap() { char *homedir, *histdir, *homedir_prefix, *hostname; time_t now; /* open debug file if necessary */ if (debug) { debug_fp = fopen(DEBUG_FILENAME, "w"); if (!debug_fp) myerror("Couldn't open debug file %s", DEBUG_FILENAME); setbuf(debug_fp, NULL); /* always write debug messages to disk at once */ } hostname = getenv("HOSTNAME") ? getenv("HOSTNAME") : "?"; now = time(NULL); DPRINTF0(DEBUG_ALL, "-*- mode: grep -*-"); DPRINTF3(DEBUG_ALL, "rlwrap version %s, host: %s, time: %s", VERSION, hostname, ctime(&now)); init_terminal(); /* Determine rlwrap home dir and prefix for default history and completion filenames */ homedir = (getenv("RLWRAP_HOME") ? getenv("RLWRAP_HOME") : getenv("HOME")); homedir_prefix = (getenv("RLWRAP_HOME") ? /* is RLWRAP_HOME set? */ add2strings(getenv("RLWRAP_HOME"), "/") : /* use $RLWRAP_HOME/<command>_history */ add2strings(getenv("HOME"), "/.")); /* if not, use ~/.<command>_history */ /* Determine history file name and check its existence and permissions */ if (history_filename) { histdir = mydirname(history_filename); } else { histdir = homedir; history_filename = add3strings(homedir_prefix, command_name, "_history"); } if (write_histfile) { if (access(history_filename, F_OK) == 0) { /* already exists, can we read/write it? */ if (access(history_filename, R_OK | W_OK) != 0) { myerror("cannot read and write %s", history_filename); } } else { /* doesn't exist, can we create it? */ if(access(histdir, W_OK) != 0) { if (errno == ENOENT) { mode_t oldmask = umask(0); if (mkdir(histdir, 0700)) /* rwx------ */ myerror("cannot create directory %s", histdir); umask(oldmask); } else { myerror("cannot create history file in %s", histdir); } } } } else { /* ! write_histfile */ if (access(history_filename, R_OK) != 0) { myerror("cannot read %s", history_filename); } } /* Initialize history */ using_history(); stifle_history(histsize); read_history(history_filename); /* ignore errors here: history file may not yet exist, but will be created on exit */ if (feed_history_into_completion_list) feed_file_into_completion_list(history_filename); /* Determine completion file name (completion files are never written to, and ignored when unreadable or non-existent) */ completion_filename = add3strings(homedir_prefix, command_name, "_completions"); default_completion_filename = add3strings(DATADIR, "/rlwrap/completions/", command_name); rl_readline_name = command_name; /* Initialise completion list (if <completion_filename> is readable) */ if (access(completion_filename, R_OK) == 0) { feed_file_into_completion_list(completion_filename); } else if (access(default_completion_filename, R_OK) == 0) { feed_file_into_completion_list(default_completion_filename); } }
/* * main loop: listen on stdin (for user input) and master pty (for command output), * and try to write output_queue to master_pty (if it is not empty) * This function never returns. */ void main_loop() { int nfds; fd_set readfds; fd_set writefds; int nread; char buf[BUFFSIZE], *timeoutstr, *old_raw_prompt, *new_output_minus_prompt; int promptlen = 0; int leave_prompt_alone; sigset_t no_signals_blocked; struct timespec select_timeout, *select_timeoutptr; struct timespec immediately = { 0, 0 }; /* zero timeout when child is dead */ struct timespec wait_a_little = {0, 0xBadf00d }; /* tv_usec field will be filled in when initialising */ struct timespec *forever = NULL; wait_a_little.tv_nsec = 1000 * 1000 * wait_before_prompt; sigemptyset(&no_signals_blocked); init_readline(""); last_minute_checks(); pass_through_filter(TAG_OUTPUT,""); /* If something is wrong with filter, get the error NOW */ set_echo(FALSE); /* This will also put the terminal in CBREAK mode */ test_main(); /* ------------------------------ main loop -------------------------------*/ while (TRUE) { /* listen on both stdin and pty_fd */ FD_ZERO(&readfds); FD_SET(STDIN_FILENO, &readfds); FD_SET(master_pty_fd, &readfds); /* try to write output_queue to master_pty (but only if it is nonempty) */ FD_ZERO(&writefds); if (output_queue_is_nonempty()) FD_SET(master_pty_fd, &writefds); DPRINTF1(DEBUG_AD_HOC, "prompt_is_still_uncooked = %d", prompt_is_still_uncooked); if (command_is_dead || ignore_queued_input) { select_timeout = immediately; select_timeoutptr = &select_timeout; timeoutstr = "immediately"; } else if (prompt_is_still_uncooked) { select_timeout = wait_a_little; select_timeoutptr = &select_timeout; timeoutstr = "wait_a_little"; } else { select_timeoutptr = forever; /* NULL */ timeoutstr = "forever"; } DPRINTF1(DEBUG_TERMIO, "calling select() with timeout %s", timeoutstr); nfds = my_pselect(1 + master_pty_fd, &readfds, &writefds, NULL, select_timeoutptr, &no_signals_blocked); DPRINTF3(DEBUG_TERMIO, "select() returned %d (stdin|pty in|pty out = %03d), within_line_edit=%d", nfds, 100*(FD_ISSET(STDIN_FILENO, &readfds)?1:0) + 10*(FD_ISSET(master_pty_fd, &readfds)?1:0) + (FD_ISSET(master_pty_fd, &writefds)?1:0), within_line_edit); assert(!filter_pid || filter_is_dead || kill(filter_pid,0) == 0); assert(command_is_dead || kill(command_pid,0) == 0); /* check flags that may have been set by signal handlers */ if (filter_is_dead) filters_last_words(); /* will call myerror with last words */ if (received_WINCH) { /* received_WINCH flag means we've had a WINCH while within_line_edit was FALSE */ DPRINTF0(DEBUG_READLINE, "Starting line edit as a result of WINCH "); within_line_edit = TRUE; restore_rl_state(); received_WINCH = FALSE; continue; } if (nfds < 0) { /* exception */ if (errno == EINTR) { /* interrupted by signal */ continue; } else myerror("select received exception"); } else if (nfds == 0) { /* timeout, which can only happen when .. */ if (ignore_queued_input) { /* ... we have read all the input keystrokes that should be ignored (i.e. those that accumulated on stdin while we were calling an external editor) */ ignore_queued_input = FALSE; continue; } else if (command_is_dead) { /* ... or else, if child is dead, ... */ DPRINTF2(DEBUG_SIGNALS, "select returned 0, command_is_dead=%d, commands_exit_status=%d", command_is_dead, commands_exit_status); cleanup_rlwrap_and_exit(EXIT_SUCCESS); } else if (prompt_is_still_uncooked) { /* cooking time? */ if (we_just_got_a_signal_or_EOF) { we_just_got_a_signal_or_EOF = FALSE; /* 1. If we got a signal/EOF before cooking time, we don't need special action to preserve the cooked prompt. 2. Reset we_just_got_a_signal_or_EOF after a signal or EOF that didn't kill command */ continue; } if (!skip_rlwrap()) { /* ... or else, it is time to cook the prompt */ if (pre_given && accepted_lines == 0) { saved_rl_state.input_buffer = mysavestring(pre_given); /* stuff pre-given text into edit buffer */ saved_rl_state.point = strlen(pre_given); DPRINTF0(DEBUG_READLINE, "Starting line edit (because of -P option)"); within_line_edit = TRUE; restore_rl_state(); continue; } if (accepted_lines == 1 && one_shot_rlwrap) cleanup_rlwrap_and_exit(EXIT_SUCCESS); move_cursor_to_start_of_prompt(ERASE); /* cooked prompt may be shorter than raw prompt, hence the ERASE */ /* move and erase before cooking, as we need to move/erase according to the raw prompt */ cook_prompt_if_necessary(); DPRINTF2(DEBUG_READLINE,"After cooking, raw_prompt=%s, cooked=%s", mangle_string_for_debug_log(saved_rl_state.raw_prompt, MANGLE_LENGTH), mangle_string_for_debug_log(saved_rl_state.cooked_prompt, MANGLE_LENGTH)); my_putstr(saved_rl_state.cooked_prompt); rlwrap_already_prompted = TRUE; } prompt_is_still_uncooked = FALSE; } else { myerror("unexpected select() timeout"); } } else if (nfds > 0) { /* Hah! something to read or write */ /* -------------------------- read pty --------------------------------- */ if (FD_ISSET(master_pty_fd, &readfds)) { /* there is something to read on master pty: */ if ((nread = read(master_pty_fd, buf, BUFFSIZE - 1)) <= 0) { /* read it */ if (command_is_dead || nread == 0) { /* child is dead or has closed its stdout */ if (promptlen > 0) /* commands dying words were not terminated by \n ... */ my_putchar('\n'); /* provide the missing \n */ cleanup_rlwrap_and_exit(EXIT_SUCCESS); } else if (errno == EINTR) /* interrupted by signal ...*/ continue; /* ... don't worry */ else myerror("read error on master pty"); } completely_mirror_slaves_output_settings(); /* some programs (e.g. joe) need this. Gasp!! */ if (skip_rlwrap()) { /* Race condition here! The client may just have finished an emacs session and returned to cooked mode, while its ncurses-riddled output is stil waiting for us to be processed. */ write_patiently(STDOUT_FILENO, buf, nread, "to stdout"); DPRINTF2(DEBUG_TERMIO, "read from pty and wrote to stdout %d bytes in direct mode <%s>", nread, mangle_string_for_debug_log((buf[nread]='\0', buf), MANGLE_LENGTH)); yield(); continue; } DPRINTF2(DEBUG_TERMIO, "read %d bytes from pty into buffer: %s", nread, mangle_string_for_debug_log((buf[nread]='\0', buf), MANGLE_LENGTH)); remove_padding_and_terminate(buf, nread); write_logfile(buf); if (within_line_edit) /* client output arrives while we're editing keyboard input: */ save_rl_state(); /* temporarily disable readline and restore the screen state before readline was called */ assert(saved_rl_state.raw_prompt != NULL); /* We *always* compute the printable part and the new raw prompt, and *always* print the printable part There are four possibilities: 1. impatient before cooking. The raw prompt has been printed, write the new output after it 2. patient before cooking No raw prompt has been printed yet, don't print anything 3. impatient after cooking 3a no current prompt print the new output 3b some current prompt erase it, replace by current raw prompt and print new output 4. patient after cooking don't print anything */ /* sometimes we want to leave the prompt standing, e.g. after accepting a line, or when a signal arrived */ leave_prompt_alone = *saved_rl_state.raw_prompt == '\0' /* saved_rl_state.raw_prompt = "" in two distinct cases: when there is actually no prompt, or just after accepting a line, when the cursor is at the end of the prompt. In both cases, we dont't want to move the cursor */ || prompt_is_still_uncooked /* in this case no prompt has been displayed yet */ || command_is_dead || (we_just_got_a_signal_or_EOF && strrchr(buf, '\n')); /* a signal followed by output with a newline in it: treat it as response to user input, so leave the prompt alone */ DPRINTF3(DEBUG_READLINE, "leave_prompt_alone: %s (raw prompt: %s, prompt_is_still_uncooked: %d)", (leave_prompt_alone? "yes" : "no"), mangle_string_for_debug_log(saved_rl_state.raw_prompt, MANGLE_LENGTH), prompt_is_still_uncooked); if (!leave_prompt_alone) /* && (!impatient_prompt || !saved_rl_state.cooked_prompt)) */ move_cursor_to_start_of_prompt(ERASE); else if (we_just_got_a_signal_or_EOF) { free (saved_rl_state.raw_prompt); saved_rl_state.raw_prompt = mysavestring(""); /* prevent reprinting the prompt */ } if (impatient_prompt && !leave_prompt_alone) old_raw_prompt = mysavestring(saved_rl_state.raw_prompt); new_output_minus_prompt = process_new_output(buf, &saved_rl_state); /* chop off the part after the last newline and put this in saved_rl_state.raw_prompt (or append buf if no newline found)*/ if (impatient_prompt) { /* in impatient mode, ALL command output is passed through the OUTPUT filter, including the prompt The prompt, however, is filtered separately at cooking time and then displayed */ char *filtered = pass_through_filter(TAG_OUTPUT, buf); if(!leave_prompt_alone) { my_putstr(old_raw_prompt); free(old_raw_prompt); } my_putstr(filtered); free (filtered); rlwrap_already_prompted = TRUE; } else { my_putstr(new_output_minus_prompt); rlwrap_already_prompted = FALSE; } free(new_output_minus_prompt); prompt_is_still_uncooked = TRUE; if (within_line_edit) restore_rl_state(); yield(); /* wait for what client has to say .... */ continue; /* ... and don't attempt to process keyboard input as long as it is talking , in order to avoid re-printing the current prompt (i.e. unfinished output line) */ } /* ----------------------------- key pressed: read stdin -------------------------*/ if (FD_ISSET(STDIN_FILENO, &readfds)) { /* key pressed */ unsigned char byte_read; /* the readline function names and documentation talk about "characters" and "keys", but we're reading bytes (i.e. unsigned chars) here, and those may very well be part of a multi-byte character. Example: hebrew "aleph" in utf-8 is 0xd790; pressing this key will make us read 2 bytes 0x90 and then 0xd7, (or maybe the other way round depending on endianness??) The readline library hides all this complexity and allows one to just "pass the bytes around" */ nread = read(STDIN_FILENO, &byte_read, 1); /* read next byte of input */ assert(sizeof(unsigned char) == 1); /* gets optimised away */ if (nread <= 0) DPRINTF1(DEBUG_TERMIO, "read from stdin returned %d", nread); if (nread < 0) if (errno == EINTR) continue; else myerror("Unexpected error"); else if (nread == 0) /* EOF on stdin */ cleanup_rlwrap_and_exit(EXIT_SUCCESS); else if (ignore_queued_input) continue; /* do nothing with it*/ assert(nread == 1); DPRINTF2(DEBUG_TERMIO, "read from stdin: byte 0x%02x (%s)", byte_read, mangle_char_for_debug_log(byte_read, TRUE)); if (skip_rlwrap()) { /* direct mode, just pass it on */ /* remote possibility of a race condition here: when the first half of a multi-byte char is read in direct mode and the second half in readline mode. Oh well... */ DPRINTF0(DEBUG_TERMIO, "passing it on (in transparent mode)"); completely_mirror_slaves_terminal_settings(); /* this is of course 1 keypress too late: we should mirror the terminal settings *before* the user presses a key. (maybe using rl_event_hook??) @@@FIXME @@@ HOW?*/ write_patiently(master_pty_fd, &byte_read, 1, "to master pty"); } else { /* hand it over to readline */ if (!within_line_edit) { /* start a new line edit */ DPRINTF0(DEBUG_READLINE, "Starting line edit"); within_line_edit = TRUE; restore_rl_state(); } if (term_eof && byte_read == term_eof && strlen(rl_line_buffer) == 0) { /* hand a term_eof (usually CTRL-D) directly to command */ char *sent_EOF = mysavestring("?"); *sent_EOF = term_eof; put_in_output_queue(sent_EOF); we_just_got_a_signal_or_EOF = TRUE; free(sent_EOF); } else { rl_stuff_char(byte_read); /* stuff it back in readline's input queue */ DPRINTF0(DEBUG_TERMIO, "passing it to readline"); DPRINTF2(DEBUG_READLINE, "rl_callback_read_char() (_rl_eof_char=%d, term_eof=%d)", _rl_eof_char, term_eof); rl_callback_read_char(); } } } /* -------------------------- write pty --------------------------------- */ if (FD_ISSET(master_pty_fd, &writefds)) { flush_output_queue(); yield(); /* give slave command time to respond. If we don't do this, nothing bad will happen, but the "dialogue" on screen will be out of order */ } } /* if (ndfs > 0) */ } /* while (1) */ } /* void main_loop() */
/* Given the actual data set <dataSet>, estimates the values for algorithm parameters that would give the optimal running time of a query. The set <sampleQueries> is a set with query sample points (R-NN DS's parameters are optimized for query points from the set <sampleQueries>). <sampleQueries> could be a sample of points from the actual query set or from the data set. When computing the estimated number of collisions of a sample query point <q> with the data set points, if there is a point in the data set with the same pointer with <q> (that is when <q> is a data set point), then the corresponding point (<q>) is not considered in the data set (for the purpose of computing the respective #collisions estimation). The return value is the estimate of the optimal parameters. */ RNNParametersT computeOptimalParameters(RealT R, RealT successProbability, IntT nPoints, IntT dimension, PPointT *dataSet, IntT nSampleQueries, PPointT *sampleQueries, MemVarT memoryUpperBound){ ASSERT(nSampleQueries > 0); initializeLSHGlobal(); RNNParametersT optParameters; optParameters.successProbability = successProbability; optParameters.dimension = dimension; optParameters.parameterR = R; #ifdef USE_L1_DISTANCE optParameters.parameterR2 = R; #else optParameters.parameterR2 = SQR(R); #endif optParameters.useUfunctions = TRUE; // TODO: could optimize here: // maybe sometimes, the old way // was better. optParameters.parameterW = PARAMETER_W_DEFAULT; optParameters.parameterT = nPoints; optParameters.typeHT = HT_HYBRID_CHAINS; // Compute the run-time parameters (timings of different parts of the algorithm). IntT nReps = 10; // # number of repetions RealT lshPrecomp = 0, uhashOver = 0, distComp = 0; for(IntT i = 0; i < nReps; i++){ RealT lP, uO, dC; determineRTCoefficients(optParameters.parameterR, optParameters.successProbability, optParameters.useUfunctions, optParameters.typeHT, optParameters.dimension, nPoints, dataSet, lP, uO, dC); lshPrecomp += lP; uhashOver += uO; distComp += dC; DPRINTF4("Coefs: lP = %0.9lf\tuO = %0.9lf\tdC = %0.9lf\n", lP, uO, dC); } lshPrecomp /= nReps; uhashOver /= nReps; distComp /= nReps; DPRINTF("Coefs (final): lshPrecomp = %0.9lf\n", lshPrecomp); DPRINTF("Coefs (final): uhashOver = %0.9lf\n", uhashOver); DPRINTF("Coefs (final): distComp = %0.9lf\n", distComp); DPRINTF("Remaining memory: %lld\n", memoryUpperBound); // Try all possible <k>s and choose the one for which the time // estimate of a query is minimal. IntT k; RealT timeLSH, timeUH, timeCycling; //IntT queryIndex = genRandomInt(0, nPoints); //PPointT query = dataSet[queryIndex]; // query points = a random points from the data set. IntT bestK = 0; RealT bestTime = 0; for(k = 2; ; k += 2){ DPRINTF("ST. k = %d\n", k); IntT m = computeMForULSH(k, successProbability); IntT L = m * (m-1) / 2; //DPRINTF("Available memory: %lld\n", getAvailableMemory()); if (L * nPoints > memoryUpperBound / 12){ break; } timeLSH = m * k * lshPrecomp; timeUH = L * uhashOver; //RealT nCollisions = estimateNCollisionsFromDSPoint(nPoints, dimension, dataSet, queryIndex, k, L, R); // Compute the mean number of collisions for the points from the sample query set. RealT nCollisions = 0; for(IntT i = 0; i < nSampleQueries; i++){ nCollisions += estimateNDistinctCollisions(nPoints, dimension, dataSet, sampleQueries[i], TRUE, k, m, R); } nCollisions /= nSampleQueries; timeCycling = nCollisions * distComp; DPRINTF3("ST.m=%d L=%d \n", m, L); DPRINTF("ST.Estimated # distinct collisions = %0.6lf\n", (double)nCollisions); DPRINTF("ST.TimeLSH = %0.6lf\n", timeLSH); DPRINTF("ST.TimeUH = %0.6lf\n", timeUH); DPRINTF("ST.TimeCycling = %0.6lf\n", timeCycling); DPRINTF("ST.Sum = %0.6lf\n", timeLSH + timeUH + timeCycling); if (bestK == 0 || (timeLSH + timeUH + timeCycling) < bestTime) { bestK = k; bestTime = timeLSH + timeUH + timeCycling; } ASSERT(k < 100); // otherwise, k reached 100 -- which, from // experience, should never happen for reasonable // data set & available memory amount. } DPRINTF("STO.Optimal k = %d\n", bestK); IntT m = computeMForULSH(bestK, successProbability); IntT L = m * (m-1) / 2; timeLSH = m * bestK * lshPrecomp; timeUH = L * uhashOver; // Compute the mean number of collisions for the points from the sample query set. RealT nCollisions = 0; for(IntT i = 0; i < nSampleQueries; i++){ nCollisions += estimateNDistinctCollisions(nPoints, dimension, dataSet, sampleQueries[i], TRUE, k, m, R); } nCollisions /= nSampleQueries; // timeCycling = estimateNCollisionsFromDSPoint(nPoints, dimension, dataSet, queryIndex, bestK, L, R) * distComp; timeCycling = nCollisions * distComp; DPRINTF("STO.TimeLSH = %0.6lf\n", timeLSH); DPRINTF("STO.TimeUH = %0.6lf\n", timeUH); DPRINTF("STO.TimeCycling = %0.6lf\n", timeCycling); DPRINTF("STO.Sum = %0.6lf\n", timeLSH + timeUH + timeCycling); optParameters.parameterK = bestK; optParameters.parameterM = m; optParameters.parameterL = L; return optParameters; }