struct queue* search_transform(void* obj, int id, void* priv,struct queue_head* in_q,struct queue_head* oq) { struct search_queue_node* sqn = obj; char* search_term = priv; fprintf(stderr,"Call search_transform [%s] on file %s \n", search_term,sqn->file_name); search_buffer(id,sqn->file_name,search_term,sqn->iovec_num,sqn->vec); return queue_create_node(sqn,sizeof(struct search_queue_node)); }
node* get(const keyType key, lsm* tree){ // search the buffer for this item nodei* ni = search_buffer(&key, tree); if(ni != NULL){ return ni->node; } else{ // search through the file on disk for this item ni = search_disk(&key, tree); if(ni != NULL){ return ni->node; } } // If it does not find the given key, it will return NULL return NULL; }
/* this is the plugin entry point */ enum plugin_status plugin_start(const void* parameter) { int ok; const char *filename = parameter; char *p; if(!parameter) return PLUGIN_ERROR; DEBUGF("%s - %s\n", (char *)parameter, &filename[rb->strlen(filename)-4]); /* Check the extension. We only allow .m3u files. */ if (!(p = rb->strrchr(filename, '.')) || (rb->strcasecmp(p, ".m3u") && rb->strcasecmp(p, ".m3u8"))) { rb->splash(HZ, "Not a .m3u or .m3u8 file"); return PLUGIN_ERROR; } rb->strcpy(path, filename); p = rb->strrchr(path, '/'); if(p) *p = 0; rb->snprintf(resultfile, MAX_PATH, "%s/search_result.m3u", path); ok = search_init(parameter); if (!ok) return PLUGIN_ERROR; search_buffer(); clear_display(); rb->splash(HZ, "Done"); rb->close(fdw); rb->close(fd); /* We fake a USB connection to force a reload of the file browser */ return PLUGIN_USB_CONNECTED; }
/** * Search the pattern from the file descriptor and add formatted matched lines to the queue if the * pattern was matched in the read buffer. This method processes follow steps: * 1. The file content will be read to a large buffer at once. * 2. Search the pattern from the read buffer. * 3. Scan new line count if need. * * This method returns match count. */ int search(int fd, const char *pattern, int pattern_len, enum file_type t, match_line_list *match_lines, int thread_no) { char eol = '\n'; size_t line_count = 0; size_t read_sum = 0; size_t n = NMAX; ssize_t read_len; int buf_offset = 0; int match_count = 0; bool do_search = false; char *buf = (char *)hw_calloc(n + 1, SIZE_OF_CHAR); char *last_new_line_scan_pos = buf; char *last_line_end; if (!op.use_regex) { prepare_fjs(pattern, pattern_len, t); } while ((read_len = read(fd, buf + buf_offset, NMAX)) > 0) { read_sum += read_len; // Search end position of the last line in the buffer. We search from the first position // and end position of the last line. size_t search_len; if (read_len < NMAX) { last_line_end = buf + read_sum; search_len = read_sum; buf[read_sum] = eol; } else { last_line_end = reverse_char(buf + buf_offset, eol, read_len); if (last_line_end == NULL) { buf = last_new_line_scan_pos = grow_buf_if_shortage(&n, read_sum, buf_offset, buf, buf); buf_offset += read_len; continue; } search_len = last_line_end - buf; } do_search = true; // Search the pattern and construct matching results. The results will be stored to list // `match_lines`. int count = search_buffer( buf, search_len, pattern, pattern_len, t, eol, &line_count, &last_new_line_scan_pos, match_lines, thread_no ); match_count += count; // If hw search the pattern from stdin stream and find the pattern in the buffer, results // are printed immedeately. if (fd == STDIN_FILENO && count > 0) { file_queue_node stream; stream.t = t; stream.match_lines = match_lines; print_result(&stream); // Release memory because matching line was already printed. clear_line_list(match_lines); } // Break loop if file pointer is reached to EOF. But if the file descriptor is stdin, we // should wait for next input. For example, if hw search from the pipe that is created by // `tail -f`, we should continue searching until receive a signal. if (fd != STDIN_FILENO && read_len < NMAX) { break; } if (op.show_line_number) { last_new_line_scan_pos = scan_newline(last_new_line_scan_pos, last_line_end, &line_count, eol); } last_line_end++; ssize_t rest = read_sum - search_len - 1; if (rest >= 0) { char *new_buf = grow_buf_if_shortage(&n, rest, 0, last_line_end, buf); if (new_buf == last_line_end) { new_buf = buf; memmove(new_buf, last_line_end, rest); } buf = last_new_line_scan_pos = new_buf; buf_offset = rest; read_sum = rest; } } tc_free(buf); return match_count; }
// Search a file (either on disk or in memory) int search_file( APTR file, UBYTE *search_text, ULONG flags, UBYTE *buffer, ULONG buffer_size) { UBYTE match_text[256]; long match_size; long search_len,buf_pos; search_handle handle; // Get length of search string search_len=strlen(search_text); // Matching hex? if (search_text[0]=='$') { // Convert hex to ASCII string for (buf_pos=1,match_size=0;buf_pos<search_len;buf_pos+=2,match_size++) { // Wildcard? if (search_text[buf_pos]=='?') match_text[match_size]='?'; // Else do hex conversion else match_text[match_size]=Atoh(&search_text[buf_pos],2); } // Can't have cast-insensitivity or only words on a hex search flags&=~(SEARCH_NOCASE|SEARCH_ONLYWORDS); } // Else normal search else { // Go through search text for (buf_pos=0,match_size=0;buf_pos<search_len;buf_pos++) { // \ indicates a control sequence if (search_text[buf_pos]=='\\') { // Increment position ++buf_pos; // If followed by another \, match a normal \ character if (search_text[buf_pos]=='\\') match_text[match_size++]='\\'; // Otherwise, indicates a decimal value else { match_text[match_size++]=atoi(search_text+buf_pos); // Skip over number while (search_text[buf_pos+1]>='0' && search_text[buf_pos+1]<='9') ++buf_pos; } } // Otherwise, store character else { // Case insensitive - convert to upper case if (flags&SEARCH_NOCASE) match_text[match_size++]=toupper(search_text[buf_pos]); // Store vertbatim else match_text[match_size++]=search_text[buf_pos]; } } } // Zero result settings handle.v_search_found_lines=0; handle.v_search_last_line_pos=0; // If we have a buffer, search it and return if (buffer) return search_buffer(&handle,buffer,buffer_size,match_text,match_size,flags); // Allocate buffer to read file into if (!(buffer=AllocVec(32004,MEMF_CLEAR))) return -1; // Loop until aborted, or end of file FOREVER { long oldpos,size; // Remember old file position oldpos=SeekBuf(file,0,OFFSET_CURRENT); // Read some data if ((size=ReadBuf(file,buffer,32000))<1) break; // Search what we've got if (search_buffer(&handle,buffer,size,match_text,match_size,flags)==1) { // Free buffer FreeVec(buffer); // Return match position return oldpos+(int)(handle.v_search_found_position-buffer); } // If end of file, break if (size<32000) break; // Seek back the size of the match (in case we had it spread over the end of the buffer) SeekBuf(file,-match_size,OFFSET_CURRENT); } // Free buffer FreeVec(buffer); // No match return -1; }
r = write_to_disk(tree); } node n; n.key = *key; n.val = *val; tree->block[tree->next_empty] = n; tree->next_empty += 1; return r; } int delete(const keyType* key, lsm* tree){ int r = 0; nodei *ni = malloc(sizeof(nodei)); // if the node is in the buffer ni = search_buffer(key, tree); if(ni != NULL){ tree->next_empty -= 1; memmove(&tree->block[ni->index], &tree->block[ni->index+1], tree->block_size-ni->index); } else { // if the node is on disk ni = search_disk(key, tree); assert(ni); FILE* fr = fopen(tree->disk1, "r"); if(fr == NULL){ perror("delete: open: \n"); } size_t num_elements = 0; node* file_data; // read number of elements r = fread(&num_elements, sizeof(size_t), 1, fr);
search_nodep do_compress(match_ctx ctx, encode_match_data emd, const char *exported_encoding, int max_passes, int use_literal_sequences) { matchp_cache_enum mpce; matchp_snp_enum snpe; search_nodep snp; search_nodep best_snp; int pass; float size; float old_size; char prev_enc[100]; const char *curr_enc; pass = 1; prev_enc[0] = '\0'; LOG(LOG_NORMAL, (" pass %d: ", pass)); if(exported_encoding != NULL) { LOG(LOG_NORMAL, ("importing %s\n", exported_encoding)); optimal_encoding_import(emd, exported_encoding); } else { LOG(LOG_NORMAL, ("optimizing ..\n")); matchp_cache_get_enum(ctx, mpce); optimal_optimize(emd, matchp_cache_enum_get_next, mpce); } best_snp = NULL; old_size = 100000000.0; for (;;) { snp = search_buffer(ctx, optimal_encode, emd, use_literal_sequences); if (snp == NULL) { LOG(LOG_ERROR, ("error: search_buffer() returned NULL\n")); exit(-1); } size = snp->total_score; LOG(LOG_NORMAL, (" size %0.1f bits ~%d bytes\n", size, (((int) size) + 7) >> 3)); if (size >= old_size) { search_node_free(snp); break; } if (best_snp != NULL) { search_node_free(best_snp); } best_snp = snp; old_size = size; ++pass; if(pass > max_passes) { break; } optimal_free(emd); optimal_init(emd); LOG(LOG_NORMAL, (" pass %d: optimizing ..\n", pass)); matchp_snp_get_enum(snp, snpe); optimal_optimize(emd, matchp_snp_enum_get_next, snpe); curr_enc = optimal_encoding_export(emd); if (strcmp(curr_enc, prev_enc) == 0) { break; } strcpy(prev_enc, curr_enc); } return best_snp; }
static search_nodep do_compress(match_ctx ctx, encode_match_data emd, int max_passes) { matchp_cache_enum mpce; matchp_snp_enum snpe; search_nodep snp; search_nodep best_snp; int pass; float old_size; pass = 1; matchp_cache_get_enum(ctx, mpce); optimal_optimize(emd, matchp_cache_enum_get_next, mpce); best_snp = NULL; old_size = 1000000.0; for (;;) { snp = search_buffer(ctx, optimal_encode, emd); if (snp == NULL) { fprintf(stderr, "error: search_buffer() returned NULL\n"); exit(-1); } float size = snp->total_score; if (size >= old_size) { #if 0 /* RH */ search_node_free(snp); #endif /* RH */ break; } #if 0 /* RH */ if (best_snp != NULL) { search_node_free(best_snp); } #endif /* RH */ best_snp = snp; old_size = size; ++pass; if (pass > max_passes) { break; } optimal_free(emd); optimal_init(emd); matchp_snp_get_enum(snp, snpe); optimal_optimize(emd, matchp_snp_enum_get_next, snpe); } return best_snp; }