/* * Lookup known nodes that are nearest to the given id. */ int kad_lookup_value( const char query[], IP addr_array[], size_t *addr_num ) { char hexbuf[SHA1_HEX_LENGTH+1]; UCHAR id[SHA1_BIN_LENGTH]; int rc; /* Generate the id, e.g. id = sha1(query) */ id_compute( id, query ); log_debug( "KAD: Lookup '%s' as '%s'.", query, str_id( id, hexbuf ) ); dht_lock(); rc = results_collect( id, addr_array, *addr_num ); if( rc < 0 ) { /* No results item found - no search in progress - start search */ dht_lock(); results_add( id, query ); dht_search( id, 0, gconf->af, dht_callback_func, NULL ); dht_unlock(); *addr_num = 0; rc = -1; } else { *addr_num = rc; rc = 0; } dht_unlock(); return rc; }
/* * Lookup known nodes that are nearest to the given id. */ int kad_lookup_value( const char _query[], IP addr_array[], size_t *addr_num ) { char query[QUERY_MAX_SIZE]; struct results_t *results; int is_new; int rc; if( query_sanitize( query, sizeof(query), _query ) != 0 ) { return -2; } log_debug( "KAD: Lookup string: %s", query ); dht_lock(); /* Find existing or create new item */ results = results_add( query, &is_new ); if( results && is_new ) { /* Search own announced values */ kad_lookup_local_values( results ); } if( results == NULL ) { /* Failed to create a new search */ rc = -1; } else if( results->done ) { /* * The search exists already but has finished. Restart the search when * no results have been found or more than half of the searches lifetime * has expired. */ if( results_entries_count( results ) == 0 || (time_now_sec() - results->start_time) > (MAX_SEARCH_LIFETIME / 2) ) { /* Mark search as in progress */ results_done( results, 0 ); /* Start another search for this id */ dht_search( results->id, 0, gconf->af, dht_callback_func, NULL ); } rc = 2; } else if( is_new ) { /* Start a new DHT search */ dht_search( results->id, 0, gconf->af, dht_callback_func, NULL ); rc = 1; } else { /* Search is still running */ rc = 0; } /* Collect addresses to be returned */ *addr_num = results_collect( results, addr_array, *addr_num ); dht_unlock(); return rc; }
void term_update_search() { int update_type = term.results.update_type; if (term.results.update_type == NO_UPDATE) return; term.results.update_type = NO_UPDATE; if (term.results.query_length == 0) return; circbuf cb; // Allocate room for the circular buffer of termlines. int lcurr = 0; if (update_type == PARTIAL_UPDATE) { // How much of the backscroll we need to update on a partial update? // Do a ceil: (x + y - 1) / y // On query_length - 1 int pstart = -((term.results.query_length + term.cols - 2) / term.cols) + term.sblines; lcurr = lcurr > pstart ? lcurr:pstart; results_partial_clear(lcurr); } else { term_clear_results(); } int llen = term.results.query_length / term.cols + 1; if (llen < 2) llen = 2; circbuf_init(&cb, llen); // Fill in our starting set of termlines. for (int i = lcurr; i < term.rows + term.sblines && cb.length < cb.capacity; ++i) { circbuf_push(&cb, fetch_line(i - term.sblines)); } int cpos = term.cols * lcurr; /* the number of matched chars in the current run */ int npos = 0; /* the number of matched cells in the current run (anpos >= npos) */ int anpos = 0; int end = term.cols * (term.rows + term.sblines); // Loop over every character and search for query. while (cpos < end) { // Determine the current position. int x = (cpos % term.cols); int y = (cpos / term.cols); // If our current position isn't in the buffer, add it in. if (y - lcurr >= llen) { circbuf_push(&cb, fetch_line(lcurr + llen - term.sblines)); ++lcurr; } termline * lll = circbuf_get(&cb, y - lcurr); termchar * chr = lll->chars + x; if (npos == 0 && cpos + term.results.query_length >= end) break; if (chr->chr != term.results.query[npos]) { // Skip the second cell of any wide characters if (chr->chr == UCSWIDE) { ++anpos; ++cpos; continue; } cpos -= npos - 1; npos = 0; anpos = 0; continue; } ++anpos; ++npos; if (term.results.query_length == npos) { int start = cpos - anpos + 1; result run = { .x = start % term.cols, .y = start / term.cols, .len = anpos }; #ifdef debug_search printf("%d, %d, %d\n", run.x, run.y, run.len); #endif results_add(run); npos = 0; anpos = 0; } ++cpos; } circbuf_destroy(&cb); }