📄 index.cc
字号:
a_delete query; delete out_of_date_files_iter;}int index_search_item_iterator::next(const linear_searcher &, const char **pp, int *lenp, reference_id *ridp){ if (found_list) { for (;;) { int tagno = *found_list; if (tagno == -1) break; found_list++; if (get_tag(tagno, searcher, pp, lenp, ridp)) return 1; } found_list = 0; next_out_of_date_file = indx->out_of_date_files; } while (next_out_of_date_file) { if (out_of_date_files_iter == 0) out_of_date_files_iter = next_out_of_date_file->make_search_item_iterator(query); if (out_of_date_files_iter->next(searcher, pp, lenp, ridp)) return 1; delete out_of_date_files_iter; out_of_date_files_iter = 0; next_out_of_date_file = next_out_of_date_file->next; } return 0;}int index_search_item_iterator::get_tag(int tagno, const linear_searcher &searcher, const char **pp, int *lenp, reference_id *ridp){ if (tagno < 0 || tagno >= indx->header.tags_size) { error("bad tag number"); return 0; } tag *tp = indx->tags + tagno; const char *filename = indx->munge_filename(indx->pool + tp->filename_index); int fd = open(filename, O_RDONLY); if (fd < 0) { error("can't open `%1': %2", filename, strerror(errno)); return 0; } struct stat sb; if (fstat(fd, &sb) < 0) { error("can't fstat: %1", strerror(errno)); close(fd); return 0; } time_t mtime = sb.st_mtime; if (mtime > indx->mtime) { indx->add_out_of_date_file(fd, filename, indx->filename_id + tp->filename_index); return 0; } int res = 0; FILE *fp = fdopen(fd, "r"); if (!fp) { error("fdopen failed"); close(fd); return 0; } if (tp->start != 0 && fseek(fp, long(tp->start), 0) < 0) error("can't seek on `%1': %2", filename, strerror(errno)); else { int length = tp->length; int err = 0; if (length == 0) { struct stat sb; if (fstat(fileno(fp), &sb) < 0) { error("can't stat `%1': %2", filename, strerror(errno)); err = 1; } else if ((sb.st_mode & S_IFMT) != S_IFREG) { error("`%1' is not a regular file", filename); err = 1; } else length = int(sb.st_size); } if (!err) { if (length + 2 > buflen) { a_delete buf; buflen = length + 2; buf = new char[buflen]; } if (fread(buf + 1, 1, length, fp) != length) error("fread on `%1' failed: %2", filename, strerror(errno)); else { buf[0] = '\n'; buf[length + 1] = '\n'; res = searcher.search(buf + 1, buf + 2 + length, pp, lenp); if (res && ridp) *ridp = reference_id(indx->filename_id + tp->filename_index, tp->start); } } } fclose(fp); return res;}const char *index_search_item::munge_filename(const char *filename){ if (filename[0] == '/') return filename; const char *cwd = pool; int need_slash = (cwd[0] != 0 && strchr(cwd, '\0')[-1] != '/'); int len = strlen(cwd) + strlen(filename) + need_slash + 1; if (len > filename_buflen) { a_delete filename_buffer; filename_buflen = len; filename_buffer = new char[len]; } strcpy(filename_buffer, cwd); if (need_slash) strcat(filename_buffer, "/"); strcat(filename_buffer, filename); return filename_buffer;}const int *index_search_item::search1(const char **pp, const char *end){ while (*pp < end && !csalnum(**pp)) *pp += 1; if (*pp >= end) return 0; const char *start = *pp; while (*pp < end && csalnum(**pp)) *pp += 1; int len = *pp - start; if (len < header.shortest) return 0; if (len > header.truncate) len = header.truncate; int is_number = 1; for (int i = 0; i < len; i++) if (csdigit(start[i])) key_buffer[i] = start[i]; else { key_buffer[i] = cmlower(start[i]); is_number = 0; } if (is_number && !(len == 4 && start[0] == '1' && start[1] == '9')) return 0; unsigned hc = hash(key_buffer, len); if (common_words_table) { for (int h = hc % common_words_table_size; common_words_table[h]; --h) { if (strlen(common_words_table[h]) == len && memcmp(common_words_table[h], key_buffer, len) == 0) return 0; if (h == 0) h = common_words_table_size; } } int li = table[int(hc % header.table_size)]; return li < 0 ? &minus_one : lists + li;}static void merge(int *result, const int *s1, const int *s2){ for (; *s1 >= 0; s1++) { while (*s2 >= 0 && *s2 < *s1) s2++; if (*s2 == *s1) *result++ = *s2; } *result++ = -1;}const int *index_search_item::search(const char *ptr, int length, int **temp_listp){ const char *end = ptr + length; if (*temp_listp) { a_delete *temp_listp; *temp_listp = 0; } const int *first_list = 0; while (ptr < end && (first_list = search1(&ptr, end)) == 0) ; if (!first_list) return 0; if (*first_list < 0) return first_list; const int *second_list = 0; while (ptr < end && (second_list = search1(&ptr, end)) == 0) ; if (!second_list) return first_list; if (*second_list < 0) return second_list; for (const int *p = first_list; *p >= 0; p++) ; int len = p - first_list; for (p = second_list; *p >= 0; p++) ; if (p - second_list < len) len = p - second_list; int *matches = new int[len + 1]; merge(matches, first_list, second_list); while (ptr < end) { const int *list = search1(&ptr, end); if (list != 0) { if (*list < 0) { a_delete matches; return list; } merge(matches, matches, list); if (*matches < 0) { a_delete matches; return &minus_one; } } } *temp_listp = matches; return matches;}void index_search_item::read_common_words_file(){ if (header.common <= 0) return; const char *common_words_file = munge_filename(strchr(pool, '\0') + 1); errno = 0; FILE *fp = fopen(common_words_file, "r"); if (!fp) { error("can't open `%1': %2", common_words_file, strerror(errno)); return; } common_words_table_size = 2*header.common + 1; while (!is_prime(common_words_table_size)) common_words_table_size++; common_words_table = new char *[common_words_table_size]; for (int i = 0; i < common_words_table_size; i++) common_words_table[i] = 0; int count = 0; int key_len = 0; for (;;) { int c = getc(fp); while (c != EOF && !csalnum(c)) c = getc(fp); if (c == EOF) break; do { if (key_len < header.truncate) key_buffer[key_len++] = cmlower(c); c = getc(fp); } while (c != EOF && csalnum(c)); if (key_len >= header.shortest) { int h = hash(key_buffer, key_len) % common_words_table_size; while (common_words_table[h]) { if (h == 0) h = common_words_table_size; --h; } common_words_table[h] = new char[key_len + 1]; memcpy(common_words_table[h], key_buffer, key_len); common_words_table[h][key_len] = '\0'; } if (++count >= header.common) break; key_len = 0; if (c == EOF) break; } fclose(fp);}void index_search_item::add_out_of_date_file(int fd, const char *filename, int fid){ for (search_item **pp = &out_of_date_files; *pp; pp = &(*pp)->next) if ((*pp)->is_named(filename)) return; *pp = make_linear_search_item(fd, filename, fid); warning("`%1' modified since `%2' created", filename, name);}void index_search_item::check_files(){ const char *pool_end = pool + header.strings_size; for (const char *ptr = strchr(ignore_fields, '\0') + 1; ptr < pool_end; ptr = strchr(ptr, '\0') + 1) { const char *path = munge_filename(ptr); struct stat sb; if (stat(path, &sb) < 0) error("can't stat `%1': %2", path, strerror(errno)); else if (sb.st_mtime > mtime) { int fd = open(path, O_RDONLY); if (fd < 0) error("can't open `%1': %2", path, strerror(errno)); else add_out_of_date_file(fd, path, filename_id + (ptr - pool)); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -