if (op == 1) { // indexing, add this message to the bucket
memcpy(&newbucket[0], cdb_bucket.ptr, cdb_bucket.len);
- memcpy(&newbucket[nmsgs++], &msgnum, sizeof(long));
+ int already_there = 0;
+ for (j=0; j<nmsgs; ++j) {
+ if (newbucket[j] == msgnum) {
+ already_there = 1;
+ }
+ }
+ if (already_there == 0) {
+ memcpy(&newbucket[nmsgs++], &msgnum, sizeof(long));
+ }
}
else if (op == 0) { // deindexing, remove this message from the bucket
// API call to perform searches.
// (This one does the "all of these words" search.)
// Caller is responsible for freeing the message list.
-void ft_search(int *fts_num_msgs, long **fts_msgs, const char *search_string) {
- Array *t = NULL;
- int i, j;
+Array *ft_search(const char *search_string) {
+ int i, j, tok;
struct cdbdata cdb_bucket;
- int num_all_msgs = 0;
- long *all_msgs = NULL;
- int num_ret_msgs = 0;
- int num_ret_alloc = 0;
- long *ret_msgs = NULL;
- int tok;
+ long msgnum, smsgnum;
+ int count;
-#if 0
- t = wordbreaker(search_string);
- if (array_len(t) > 0) {
- for (i=0; i<array_len(t); ++i) {
+ Array *r = array_new(sizeof(long));
+ if (!r) return(NULL);
+ Array *t = wordbreaker(search_string);
- // search for tokens[i]
+ if ((t != NULL) && (array_len(t) > 0)) {
+ for (i=0; i<array_len(t); ++i) {
memcpy(&tok, array_get_element_at(t, i), sizeof(int));
-
- // fetch the bucket, Liza
- if (ftc_msgs[tok] == NULL) {
- cdb_bucket = cdb_fetch(CDB_FULLTEXT, &tok, sizeof(int));
- if (cdb_bucket.ptr != NULL) {
- ftc_num_msgs[tok] = cdb_bucket.len / sizeof(long);
- ftc_msgs[tok] = (long *) malloc(cdb_bucket.len);
- memcpy(ftc_msgs[tok], cdb_bucket.ptr, cdb_bucket.len);
- }
- else {
- ftc_num_msgs[tok] = 0;
- ftc_msgs[tok] = malloc(sizeof(long));
+ cdb_bucket = cdb_fetch(CDB_FULLTEXT, &tok, sizeof(int));
+ if (cdb_bucket.ptr != NULL) {
+ for (j=0; j<(cdb_bucket.len / sizeof(long)); ++j) {
+ memcpy(&msgnum, cdb_bucket.ptr + (j*sizeof(long)), sizeof(long));
+ array_append(r, &msgnum);
}
}
+ }
+ }
- num_all_msgs += ftc_num_msgs[tok];
- if (num_all_msgs > 0) {
- all_msgs = realloc(all_msgs, num_all_msgs*sizeof(long) );
- memcpy(&all_msgs[num_all_msgs-ftc_num_msgs[tok]], ftc_msgs[tok], ftc_num_msgs[tok]*sizeof(long) );
+ // We need to return any message containing ALL of the tokens.
+ // If a message number appears in the array `n` times, where `n` is the number of search words,
+ // that means it matched all search words.
+ array_sort(r, longcmp);
+ for (i=0; i<array_len(r); ++i) {
+ memcpy(&msgnum, array_get_element_at(r, i), sizeof(long));
+ count = 1;
+ for (j=i+1; j<array_len(r); ++j) {
+ memcpy(&smsgnum, array_get_element_at(r, j), sizeof(long));
+ if (msgnum == smsgnum) {
+ ++count;
+ array_delete_element_at(r, j);
+ --j;
}
-
}
- array_free(t);
- if (all_msgs != NULL) {
- qsort(all_msgs, num_all_msgs, sizeof(long), longcmp);
-
- // At this point, if a message appears array_len(t) times in the
- // list, then it contains all of the search tokens.
- if (num_all_msgs >= array_len(t))
- for (j=0; j<(num_all_msgs-array_len(t)+1); ++j) {
- if (all_msgs[j] == all_msgs[j+array_len(t)-1]) {
- ++num_ret_msgs;
- if (num_ret_msgs > num_ret_alloc) {
- num_ret_alloc += 64;
- ret_msgs = realloc(ret_msgs, (num_ret_alloc*sizeof(long)) );
- }
- ret_msgs[num_ret_msgs - 1] = all_msgs[j];
-
- }
- }
- free(all_msgs);
+ if (count != array_len(t)) {
+ array_delete_element_at(r, i);
+ --i;
}
}
- *fts_num_msgs = num_ret_msgs;
- *fts_msgs = ret_msgs;
-#endif
+ array_free(t);
+ return(r);
}
// This search command is for diagnostic purposes and may be removed or replaced.
void cmd_srch(char *argbuf) {
- int num_msgs = 0;
- long *msgs = NULL;
int i;
- char search_string[256];
+ char search_string[SIZ];
+ Array *matches = NULL;
+ long msgnum;
if (CtdlAccessCheck(ac_logged_in)) return;
}
extract_token(search_string, argbuf, 0, '|', sizeof search_string);
- ft_search(&num_msgs, &msgs, search_string);
+ matches = ft_search(search_string);
- cprintf("%d %d msgs match all search words:\n", LISTING_FOLLOWS, num_msgs);
- if (num_msgs > 0) {
- for (i=0; i<num_msgs; ++i) {
- cprintf("%ld\n", msgs[i]);
+ cprintf("%d %d msgs match all search words:\n", LISTING_FOLLOWS, array_len(matches));
+ if ((matches != NULL) && (array_len(matches) > 0)) {
+ for (i=0; i<array_len(matches); ++i) {
+ memcpy(&msgnum, array_get_element_at(matches, i), sizeof(long));
+ cprintf("%ld\n", msgnum);
}
}
- if (msgs != NULL) free(msgs);
+ if (matches != NULL) {
+ array_free(matches);
+ }
cprintf("000\n");
}