kd_search.c
/* 
   1) generate a list of words from the userid 
   2) for each word, look up the keyid's associated with it
   3)    intersect-merge the keyid lists
   4) for each keyid in the resulting list
   5)    look up the matching keys
   6)    process each key into the output xbuffer

   */
1) generate a list of words from the userid
2) for each word, look up the keyid's associated with it
3)    intersect-merge the keyid lists
4) for each keyid in the resulting list
5)    look up the matching keys
6)    process each key into the output xbuffer
1 ) generate a list of words from the userid 2 ) for each word look up the keyid ' s associated with it 3 ) intersect - merge the keyid lists 4 ) for each keyid in the resulting list 5 ) look up the matching keys 6 ) process each key into the output xbuffer
int do_by_userid(kd_txn tid, unsigned char *userid, long len, int flags,
		 int maxkeys, llist_iter func, search_llist_filter filt,
		 void *c, error *err)
{
   llist words;
   wki_state wkis;
   ow_state ows;
   int key_count;
   llist_alloc(&words);
   if (len > 255) {
       err->fatal = 0;
       err->str = "search userid may not be longer than 255 characters";
       return(0);
   }
   if (!kd_add_userid_to_wordlist(&words, userid, len)) {
      err->fatal = 1;
      err->str = "adding userid search words to word list failed";
      fail();
   }
   if (llist_count(&words) == 0) {
      err->fatal = 0;
      err->str = "search userid did not contain any words";
      return(0);
   }
   wkis.tid = tid;
   wkis.first = 1;
   llist_alloc(&(wkis.wdes));
   wkis.err = err;
   err->fatal = 1;
   strcpy(err->buf, "internal error intersecting word lists");
   if (!llist_iterate(&words, word_key_intersect, &wkis))
      return(0);
   key_count = llist_count(&(wkis.wdes));
   if (key_count == 0) {
      llist_iterate(&(wkis.wdes), malloc_elem_free, NULL);
      llist_free(&(wkis.wdes));
      llist_iterate(&words, malloc_elem_free, NULL);
      llist_free(&words);
      err->fatal = 0;
      err->str = "No matching keys in database";
      return(0);
   } else if ((maxkeys >= 0) &&
	      (key_count > maxkeys)) {
      llist_iterate(&(wkis.wdes), malloc_elem_free, NULL);
      llist_free(&(wkis.wdes));
      llist_iterate(&words, malloc_elem_free, NULL);
      llist_free(&words);
      err->fatal = 0;
      sprintf(err->buf,"Number of keys in reply (%d) exceeded maximum "
	      "allowed (%d)\nTry a more specific query.\n",
	      key_count, maxkeys);
      return(0);
   }
   err->fatal = 1;
   strcpy(err->buf, "internal error generating key list");
   ows.tid = tid;
   if (flags & KD_SEARCH_EXACT) {
      ows.userid = userid;
      ows.userid_len = len;
   } else {
      ows.userid = NULL;
      ows.userid_len = 0;
   }
   ows.filter = filt;
   ows.return_disabled = (flags & KD_SEARCH_RETURN_DISABLED)?1:0;
   ows.c = c;
   ows.err = err;
   ows.append = func;
   if (!llist_iterate(&(wkis.wdes), kd_output_wde, &ows)) {
      llist_iterate(&(wkis.wdes), malloc_elem_free, NULL);
      llist_free(&(wkis.wdes));
      llist_iterate(&words, malloc_elem_free, NULL);
      llist_free(&words);
      return(0);
   }
   llist_iterate(&(wkis.wdes), malloc_elem_free, NULL);
   llist_free(&(wkis.wdes));
   llist_iterate(&words, malloc_elem_free, NULL);
   llist_free(&words);
   return(1);
}
int do_by_userid ( kd_txn tid , unsigned char * userid , long len , int flags , int maxkeys , llist_iter func , search_llist_filter filt , void * c , error * err ) { llist words ; wki_state wkis ; ow_state ows ; int key_count ; llist_alloc ( & words ) ; if ( len > 255 ) { err -> fatal = 0 ; err -> str = " " ; return ( 0 ) ; } if ( ! kd_add_userid_to_wordlist ( & words , userid , len ) ) { err -> fatal = 1 ; err -> str = " " ; fail ( ) ; } if ( llist_count ( & words ) == 0 ) { err -> fatal = 0 ; err -> str = " " ; return ( 0 ) ; } wkis . tid = tid ; wkis . first = 1 ; llist_alloc ( & ( wkis . wdes ) ) ; wkis . err = err ; err -> fatal = 1 ; strcpy ( err -> buf , " " ) ; if ( ! llist_iterate ( & words , word_key_intersect , & wkis ) ) return ( 0 ) ; key_count = llist_count ( & ( wkis . wdes ) ) ; if ( key_count == 0 ) { llist_iterate ( & ( wkis . wdes ) , malloc_elem_free , NULL ) ; llist_free ( & ( wkis . wdes ) ) ; llist_iterate ( & words , malloc_elem_free , NULL ) ; llist_free ( & words ) ; err -> fatal = 0 ; err -> str = " " ; return ( 0 ) ; } else if ( ( maxkeys >= 0 ) && ( key_count > maxkeys ) ) { llist_iterate ( & ( wkis . wdes ) , malloc_elem_free , NULL ) ; llist_free ( & ( wkis . wdes ) ) ; llist_iterate ( & words , malloc_elem_free , NULL ) ; llist_free ( & words ) ; err -> fatal = 0 ; sprintf ( err -> buf , " " " \n \n " , key_count , maxkeys ) ; return ( 0 ) ; } err -> fatal = 1 ; strcpy ( err -> buf , " " ) ; ows . tid = tid ; if ( flags & KD_SEARCH_EXACT ) { ows . userid = userid ; ows . userid_len = len ; } else { ows . userid = NULL ; ows . userid_len = 0 ; } ows . filter = filt ; ows . return_disabled = ( flags & KD_SEARCH_RETURN_DISABLED ) ? 1 : 0 ; ows . c = c ; ows . err = err ; ows . append = func ; if ( ! llist_iterate ( & ( wkis . wdes ) , kd_output_wde , & ows ) ) { llist_iterate ( & ( wkis . wdes ) , malloc_elem_free , NULL ) ; llist_free ( & ( wkis . wdes ) ) ; llist_iterate ( & words , malloc_elem_free , NULL ) ; llist_free ( & words ) ; return ( 0 ) ; } llist_iterate ( & ( wkis . wdes ) , malloc_elem_free , NULL ) ; llist_free ( & ( wkis . wdes ) ) ; llist_iterate ( & words , malloc_elem_free , NULL ) ; llist_free ( & words ) ; return ( 1 ) ; }
1) generate a list of words from the userid
2) for each word, look up the keyid's associated with it
3)    intersect-merge the keyid lists
4) for each keyid in the resulting list
5)    look up the matching keys
6)    process each key into the output xbuffer
1 ) generate a list of words from the userid 2 ) for each word look up the keyid ' s associated with it 3 ) intersect - merge the keyid lists 4 ) for each keyid in the resulting list 5 ) look up the matching keys 6 ) process each key into the output xbuffer
/* if the search userid is longer than any valid userid, fail. */ /* generate the word list */ /* if there aren't any words, fail */ /* this is a default error */ /* from that, generate the keyid list */ /* if there aren't any keyids, fail */ /* this can happen a lot */ /* lastly, generate a key list */ /* this is a default error */