| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- /*
- * lws-api-test-fts - lws full-text search api test
- *
- * Written in 2010-2019 by Andy Green <[email protected]>
- *
- * This file is made available under the Creative Commons CC0 1.0
- * Universal Public Domain Dedication.
- */
- #include <libwebsockets.h>
- #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
- #include <getopt.h>
- #endif
- #include <fcntl.h>
- #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
- static struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "createindex", no_argument, NULL, 'c' },
- { "index", required_argument, NULL, 'i' },
- { "debug", required_argument, NULL, 'd' },
- { "file", required_argument, NULL, 'f' },
- { "lines", required_argument, NULL, 'l' },
- { NULL, 0, 0, 0 }
- };
- #endif
- static const char *index_filepath = "/tmp/lws-fts-test-index";
- static char filepath[256];
- int main(int argc, char **argv)
- {
- int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE;
- int fd, fi, ft, createindex = 0, flags = LWSFTS_F_QUERY_AUTOCOMPLETE;
- struct lws_fts_search_params params;
- struct lws_fts_result *result;
- struct lws_fts_file *jtf;
- struct lws_fts *t;
- char buf[16384];
- do {
- #if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32)
- n = getopt_long(argc, argv, "hd:i:cfl", options, NULL);
- #else
- n = getopt(argc, argv, "hd:i:cfl");
- #endif
- if (n < 0)
- continue;
- switch (n) {
- case 'i':
- strncpy(filepath, optarg, sizeof(filepath) - 1);
- filepath[sizeof(filepath) - 1] = '\0';
- index_filepath = filepath;
- break;
- case 'd':
- logs = atoi(optarg);
- break;
- case 'c':
- createindex = 1;
- break;
- case 'f':
- flags &= ~LWSFTS_F_QUERY_AUTOCOMPLETE;
- flags |= LWSFTS_F_QUERY_FILES;
- break;
- case 'l':
- flags |= LWSFTS_F_QUERY_FILES |
- LWSFTS_F_QUERY_FILE_LINES;
- break;
- case 'h':
- fprintf(stderr,
- "Usage: %s [--createindex]"
- "[--index=<index filepath>] "
- "[-d <log bitfield>] file1 file2 \n",
- argv[0]);
- exit(1);
- }
- } while (n >= 0);
- lws_set_log_level(logs, NULL);
- lwsl_user("LWS API selftest: full-text search\n");
- if (createindex) {
- lwsl_notice("Creating index\n");
- /*
- * create an index by shifting through argv and indexing each
- * file given there into a single combined index
- */
- ft = open(index_filepath, O_CREAT | O_WRONLY | O_TRUNC, 0600);
- if (ft < 0) {
- lwsl_err("%s: can't open index %s\n", __func__,
- index_filepath);
- goto bail;
- }
- t = lws_fts_create(ft);
- if (!t) {
- lwsl_err("%s: Unable to allocate trie\n", __func__);
- goto bail1;
- }
- while (optind < argc) {
- fi = lws_fts_file_index(t, argv[optind],
- strlen(argv[optind]), 1);
- if (fi < 0) {
- lwsl_err("%s: Failed to get file idx for %s\n",
- __func__, argv[optind]);
- goto bail1;
- }
- fd = open(argv[optind], O_RDONLY);
- if (fd < 0) {
- lwsl_err("unable to open %s for read\n",
- argv[optind]);
- goto bail;
- }
- do {
- int n = read(fd, buf, sizeof(buf));
- if (n <= 0)
- break;
- if (lws_fts_fill(t, fi, buf, n)) {
- lwsl_err("%s: lws_fts_fill failed\n",
- __func__);
- close(fd);
- goto bail;
- }
- } while (1);
- close(fd);
- optind++;
- }
- if (lws_fts_serialize(t)) {
- lwsl_err("%s: serialize failed\n", __func__);
- goto bail;
- }
- lws_fts_destroy(&t);
- close(ft);
- return 0;
- }
- /*
- * shift through argv searching for each token
- */
- jtf = lws_fts_open(index_filepath);
- if (!jtf)
- goto bail;
- while (optind < argc) {
- struct lws_fts_result_autocomplete *ac;
- struct lws_fts_result_filepath *fp;
- uint32_t *l, n;
- memset(¶ms, 0, sizeof(params));
- params.needle = argv[optind];
- params.flags = flags;
- params.max_autocomplete = 20;
- params.max_files = 20;
- result = lws_fts_search(jtf, ¶ms);
- if (!result) {
- lwsl_err("%s: search failed\n", __func__);
- lws_fts_close(jtf);
- goto bail;
- }
- ac = result->autocomplete_head;
- fp = result->filepath_head;
- if (!ac)
- lwsl_notice("%s: no autocomplete results\n", __func__);
- while (ac) {
- lwsl_notice("%s: AC %s: %d agg hits\n", __func__,
- ((char *)(ac + 1)), ac->instances);
- ac = ac->next;
- }
- if (!fp)
- lwsl_notice("%s: no filepath results\n", __func__);
- while (fp) {
- lwsl_notice("%s: %s: (%d lines) %d hits \n", __func__,
- (((char *)(fp + 1)) + fp->matches_length),
- fp->lines_in_file, fp->matches);
- if (fp->matches_length) {
- l = (uint32_t *)(fp + 1);
- n = 0;
- while ((int)n++ < fp->matches)
- lwsl_notice(" %d\n", *l++);
- }
- fp = fp->next;
- }
- lwsac_free(¶ms.results_head);
- optind++;
- }
- lws_fts_close(jtf);
- return 0;
- bail1:
- close(ft);
- bail:
- lwsl_user("FAILED\n");
- return 1;
- }
|