1d4afb5ceSopenharmony_ci/* 2d4afb5ceSopenharmony_ci * lws-api-test-fts - lws full-text search api test 3d4afb5ceSopenharmony_ci * 4d4afb5ceSopenharmony_ci * Written in 2010-2019 by Andy Green <andy@warmcat.com> 5d4afb5ceSopenharmony_ci * 6d4afb5ceSopenharmony_ci * This file is made available under the Creative Commons CC0 1.0 7d4afb5ceSopenharmony_ci * Universal Public Domain Dedication. 8d4afb5ceSopenharmony_ci */ 9d4afb5ceSopenharmony_ci 10d4afb5ceSopenharmony_ci#include <libwebsockets.h> 11d4afb5ceSopenharmony_ci#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32) 12d4afb5ceSopenharmony_ci#include <getopt.h> 13d4afb5ceSopenharmony_ci#endif 14d4afb5ceSopenharmony_ci#include <fcntl.h> 15d4afb5ceSopenharmony_ci 16d4afb5ceSopenharmony_ci#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32) 17d4afb5ceSopenharmony_cistatic struct option options[] = { 18d4afb5ceSopenharmony_ci { "help", no_argument, NULL, 'h' }, 19d4afb5ceSopenharmony_ci { "createindex", no_argument, NULL, 'c' }, 20d4afb5ceSopenharmony_ci { "index", required_argument, NULL, 'i' }, 21d4afb5ceSopenharmony_ci { "debug", required_argument, NULL, 'd' }, 22d4afb5ceSopenharmony_ci { "file", required_argument, NULL, 'f' }, 23d4afb5ceSopenharmony_ci { "lines", required_argument, NULL, 'l' }, 24d4afb5ceSopenharmony_ci { NULL, 0, 0, 0 } 25d4afb5ceSopenharmony_ci}; 26d4afb5ceSopenharmony_ci#endif 27d4afb5ceSopenharmony_ci 28d4afb5ceSopenharmony_cistatic const char *index_filepath = "/tmp/lws-fts-test-index"; 29d4afb5ceSopenharmony_cistatic char filepath[256]; 30d4afb5ceSopenharmony_ci 31d4afb5ceSopenharmony_ciint main(int argc, char **argv) 32d4afb5ceSopenharmony_ci{ 33d4afb5ceSopenharmony_ci int n, logs = LLL_USER | LLL_ERR | LLL_WARN | LLL_NOTICE; 34d4afb5ceSopenharmony_ci int fd, fi, ft, createindex = 0, flags = LWSFTS_F_QUERY_AUTOCOMPLETE; 35d4afb5ceSopenharmony_ci struct lws_fts_search_params params; 36d4afb5ceSopenharmony_ci struct lws_fts_result *result; 37d4afb5ceSopenharmony_ci struct lws_fts_file *jtf; 38d4afb5ceSopenharmony_ci struct lws_fts *t; 39d4afb5ceSopenharmony_ci char buf[16384]; 40d4afb5ceSopenharmony_ci 41d4afb5ceSopenharmony_ci do { 42d4afb5ceSopenharmony_ci#if defined(LWS_HAS_GETOPT_LONG) || defined(WIN32) 43d4afb5ceSopenharmony_ci n = getopt_long(argc, argv, "hd:i:cfl", options, NULL); 44d4afb5ceSopenharmony_ci#else 45d4afb5ceSopenharmony_ci n = getopt(argc, argv, "hd:i:cfl"); 46d4afb5ceSopenharmony_ci#endif 47d4afb5ceSopenharmony_ci if (n < 0) 48d4afb5ceSopenharmony_ci continue; 49d4afb5ceSopenharmony_ci switch (n) { 50d4afb5ceSopenharmony_ci case 'i': 51d4afb5ceSopenharmony_ci strncpy(filepath, optarg, sizeof(filepath) - 1); 52d4afb5ceSopenharmony_ci filepath[sizeof(filepath) - 1] = '\0'; 53d4afb5ceSopenharmony_ci index_filepath = filepath; 54d4afb5ceSopenharmony_ci break; 55d4afb5ceSopenharmony_ci case 'd': 56d4afb5ceSopenharmony_ci logs = atoi(optarg); 57d4afb5ceSopenharmony_ci break; 58d4afb5ceSopenharmony_ci case 'c': 59d4afb5ceSopenharmony_ci createindex = 1; 60d4afb5ceSopenharmony_ci break; 61d4afb5ceSopenharmony_ci case 'f': 62d4afb5ceSopenharmony_ci flags &= ~LWSFTS_F_QUERY_AUTOCOMPLETE; 63d4afb5ceSopenharmony_ci flags |= LWSFTS_F_QUERY_FILES; 64d4afb5ceSopenharmony_ci break; 65d4afb5ceSopenharmony_ci case 'l': 66d4afb5ceSopenharmony_ci flags |= LWSFTS_F_QUERY_FILES | 67d4afb5ceSopenharmony_ci LWSFTS_F_QUERY_FILE_LINES; 68d4afb5ceSopenharmony_ci break; 69d4afb5ceSopenharmony_ci case 'h': 70d4afb5ceSopenharmony_ci fprintf(stderr, 71d4afb5ceSopenharmony_ci "Usage: %s [--createindex]" 72d4afb5ceSopenharmony_ci "[--index=<index filepath>] " 73d4afb5ceSopenharmony_ci "[-d <log bitfield>] file1 file2 \n", 74d4afb5ceSopenharmony_ci argv[0]); 75d4afb5ceSopenharmony_ci exit(1); 76d4afb5ceSopenharmony_ci } 77d4afb5ceSopenharmony_ci } while (n >= 0); 78d4afb5ceSopenharmony_ci 79d4afb5ceSopenharmony_ci lws_set_log_level(logs, NULL); 80d4afb5ceSopenharmony_ci lwsl_user("LWS API selftest: full-text search\n"); 81d4afb5ceSopenharmony_ci 82d4afb5ceSopenharmony_ci if (createindex) { 83d4afb5ceSopenharmony_ci 84d4afb5ceSopenharmony_ci lwsl_notice("Creating index\n"); 85d4afb5ceSopenharmony_ci 86d4afb5ceSopenharmony_ci /* 87d4afb5ceSopenharmony_ci * create an index by shifting through argv and indexing each 88d4afb5ceSopenharmony_ci * file given there into a single combined index 89d4afb5ceSopenharmony_ci */ 90d4afb5ceSopenharmony_ci 91d4afb5ceSopenharmony_ci ft = open(index_filepath, O_CREAT | O_WRONLY | O_TRUNC, 0600); 92d4afb5ceSopenharmony_ci if (ft < 0) { 93d4afb5ceSopenharmony_ci lwsl_err("%s: can't open index %s\n", __func__, 94d4afb5ceSopenharmony_ci index_filepath); 95d4afb5ceSopenharmony_ci 96d4afb5ceSopenharmony_ci goto bail; 97d4afb5ceSopenharmony_ci } 98d4afb5ceSopenharmony_ci 99d4afb5ceSopenharmony_ci t = lws_fts_create(ft); 100d4afb5ceSopenharmony_ci if (!t) { 101d4afb5ceSopenharmony_ci lwsl_err("%s: Unable to allocate trie\n", __func__); 102d4afb5ceSopenharmony_ci 103d4afb5ceSopenharmony_ci goto bail1; 104d4afb5ceSopenharmony_ci } 105d4afb5ceSopenharmony_ci 106d4afb5ceSopenharmony_ci while (optind < argc) { 107d4afb5ceSopenharmony_ci 108d4afb5ceSopenharmony_ci fi = lws_fts_file_index(t, argv[optind], 109d4afb5ceSopenharmony_ci (int)strlen(argv[optind]), 1); 110d4afb5ceSopenharmony_ci if (fi < 0) { 111d4afb5ceSopenharmony_ci lwsl_err("%s: Failed to get file idx for %s\n", 112d4afb5ceSopenharmony_ci __func__, argv[optind]); 113d4afb5ceSopenharmony_ci 114d4afb5ceSopenharmony_ci goto bail1; 115d4afb5ceSopenharmony_ci } 116d4afb5ceSopenharmony_ci 117d4afb5ceSopenharmony_ci fd = open(argv[optind], O_RDONLY); 118d4afb5ceSopenharmony_ci if (fd < 0) { 119d4afb5ceSopenharmony_ci lwsl_err("unable to open %s for read\n", 120d4afb5ceSopenharmony_ci argv[optind]); 121d4afb5ceSopenharmony_ci goto bail; 122d4afb5ceSopenharmony_ci } 123d4afb5ceSopenharmony_ci 124d4afb5ceSopenharmony_ci do { 125d4afb5ceSopenharmony_ci int n = (int)read(fd, buf, sizeof(buf)); 126d4afb5ceSopenharmony_ci 127d4afb5ceSopenharmony_ci if (n <= 0) 128d4afb5ceSopenharmony_ci break; 129d4afb5ceSopenharmony_ci 130d4afb5ceSopenharmony_ci if (lws_fts_fill(t, (uint32_t)fi, buf, (size_t)n)) { 131d4afb5ceSopenharmony_ci lwsl_err("%s: lws_fts_fill failed\n", 132d4afb5ceSopenharmony_ci __func__); 133d4afb5ceSopenharmony_ci close(fd); 134d4afb5ceSopenharmony_ci 135d4afb5ceSopenharmony_ci goto bail; 136d4afb5ceSopenharmony_ci } 137d4afb5ceSopenharmony_ci 138d4afb5ceSopenharmony_ci } while (1); 139d4afb5ceSopenharmony_ci 140d4afb5ceSopenharmony_ci close(fd); 141d4afb5ceSopenharmony_ci optind++; 142d4afb5ceSopenharmony_ci } 143d4afb5ceSopenharmony_ci 144d4afb5ceSopenharmony_ci if (lws_fts_serialize(t)) { 145d4afb5ceSopenharmony_ci lwsl_err("%s: serialize failed\n", __func__); 146d4afb5ceSopenharmony_ci 147d4afb5ceSopenharmony_ci goto bail; 148d4afb5ceSopenharmony_ci } 149d4afb5ceSopenharmony_ci 150d4afb5ceSopenharmony_ci lws_fts_destroy(&t); 151d4afb5ceSopenharmony_ci close(ft); 152d4afb5ceSopenharmony_ci 153d4afb5ceSopenharmony_ci return 0; 154d4afb5ceSopenharmony_ci } 155d4afb5ceSopenharmony_ci 156d4afb5ceSopenharmony_ci /* 157d4afb5ceSopenharmony_ci * shift through argv searching for each token 158d4afb5ceSopenharmony_ci */ 159d4afb5ceSopenharmony_ci 160d4afb5ceSopenharmony_ci jtf = lws_fts_open(index_filepath); 161d4afb5ceSopenharmony_ci if (!jtf) 162d4afb5ceSopenharmony_ci goto bail; 163d4afb5ceSopenharmony_ci 164d4afb5ceSopenharmony_ci while (optind < argc) { 165d4afb5ceSopenharmony_ci 166d4afb5ceSopenharmony_ci struct lws_fts_result_autocomplete *ac; 167d4afb5ceSopenharmony_ci struct lws_fts_result_filepath *fp; 168d4afb5ceSopenharmony_ci uint32_t *l, n; 169d4afb5ceSopenharmony_ci 170d4afb5ceSopenharmony_ci memset(¶ms, 0, sizeof(params)); 171d4afb5ceSopenharmony_ci 172d4afb5ceSopenharmony_ci params.needle = argv[optind]; 173d4afb5ceSopenharmony_ci params.flags = flags; 174d4afb5ceSopenharmony_ci params.max_autocomplete = 20; 175d4afb5ceSopenharmony_ci params.max_files = 20; 176d4afb5ceSopenharmony_ci 177d4afb5ceSopenharmony_ci result = lws_fts_search(jtf, ¶ms); 178d4afb5ceSopenharmony_ci 179d4afb5ceSopenharmony_ci if (!result) { 180d4afb5ceSopenharmony_ci lwsl_err("%s: search failed\n", __func__); 181d4afb5ceSopenharmony_ci lws_fts_close(jtf); 182d4afb5ceSopenharmony_ci goto bail; 183d4afb5ceSopenharmony_ci } 184d4afb5ceSopenharmony_ci 185d4afb5ceSopenharmony_ci ac = result->autocomplete_head; 186d4afb5ceSopenharmony_ci fp = result->filepath_head; 187d4afb5ceSopenharmony_ci 188d4afb5ceSopenharmony_ci if (!ac) 189d4afb5ceSopenharmony_ci lwsl_notice("%s: no autocomplete results\n", __func__); 190d4afb5ceSopenharmony_ci 191d4afb5ceSopenharmony_ci while (ac) { 192d4afb5ceSopenharmony_ci lwsl_notice("%s: AC %s: %d agg hits\n", __func__, 193d4afb5ceSopenharmony_ci ((char *)(ac + 1)), ac->instances); 194d4afb5ceSopenharmony_ci 195d4afb5ceSopenharmony_ci ac = ac->next; 196d4afb5ceSopenharmony_ci } 197d4afb5ceSopenharmony_ci 198d4afb5ceSopenharmony_ci if (!fp) 199d4afb5ceSopenharmony_ci lwsl_notice("%s: no filepath results\n", __func__); 200d4afb5ceSopenharmony_ci 201d4afb5ceSopenharmony_ci while (fp) { 202d4afb5ceSopenharmony_ci lwsl_notice("%s: %s: (%d lines) %d hits \n", __func__, 203d4afb5ceSopenharmony_ci (((char *)(fp + 1)) + fp->matches_length), 204d4afb5ceSopenharmony_ci fp->lines_in_file, fp->matches); 205d4afb5ceSopenharmony_ci 206d4afb5ceSopenharmony_ci if (fp->matches_length) { 207d4afb5ceSopenharmony_ci l = (uint32_t *)(fp + 1); 208d4afb5ceSopenharmony_ci n = 0; 209d4afb5ceSopenharmony_ci while ((int)n++ < fp->matches) 210d4afb5ceSopenharmony_ci lwsl_notice(" %d\n", *l++); 211d4afb5ceSopenharmony_ci } 212d4afb5ceSopenharmony_ci fp = fp->next; 213d4afb5ceSopenharmony_ci } 214d4afb5ceSopenharmony_ci 215d4afb5ceSopenharmony_ci lwsac_free(¶ms.results_head); 216d4afb5ceSopenharmony_ci 217d4afb5ceSopenharmony_ci optind++; 218d4afb5ceSopenharmony_ci } 219d4afb5ceSopenharmony_ci 220d4afb5ceSopenharmony_ci lws_fts_close(jtf); 221d4afb5ceSopenharmony_ci 222d4afb5ceSopenharmony_ci return 0; 223d4afb5ceSopenharmony_ci 224d4afb5ceSopenharmony_cibail1: 225d4afb5ceSopenharmony_ci close(ft); 226d4afb5ceSopenharmony_cibail: 227d4afb5ceSopenharmony_ci lwsl_user("FAILED\n"); 228d4afb5ceSopenharmony_ci 229d4afb5ceSopenharmony_ci return 1; 230d4afb5ceSopenharmony_ci} 231