00001 // 00002 // WordResults.cc 00003 // 00004 // Part of the ht://Dig package <http://www.htdig.org/> 00005 // Copyright (c) 1999, 2000, 2001 The ht://Dig Group 00006 // For copyright details, see the file COPYING in your distribution 00007 // or the GNU General Public License version 2 or later 00008 // <http://www.gnu.org/copyleft/gpl.html> 00009 // 00010 // $Id: WordResults_8cc-source.html,v 1.1 2008年06月08日 10:13:22 sebdiaz Exp $ 00011 // 00012 #ifdef HAVE_CONFIG_H 00013 #include "config.h" 00014 #endif /* HAVE_CONFIG_H */ 00015 00016 #include <fcntl.h> 00017 #include <unistd.h> 00018 #include <sys/stat.h> 00019 00020 #include <WordCursor.h> 00021 #include <WordTree.h> 00022 #include <WordResults.h> 00023 00024 #define WORD_RESULT_PAGESIZE 1024 00025 00026 static int wordResults_cmp(const DBT* a, const DBT* b) 00027 { 00028 int length = (int)a->app_private; 00029 00030 WordKeyNum* a_values = (WordKeyNum*)a->data; 00031 WordKeyNum* b_values = (WordKeyNum*)b->data; 00032 for(int i = 0; i < length; i++) { 00033 if(a_values[i] != b_values[i]) { 00034 return a_values[i] > b_values[i] ? 1 : -1; 00035 } 00036 } 00037 return 0; 00038 } 00039 00040 int WordResults::Open(char* namep) 00041 { 00042 if(document_length == 0) { 00043 fprintf(stderr, "WordListKey::Open: key semantic must be set (using method KeySemantic) before the Open method is called\n"); 00044 return NOTOK; 00045 } 00046 00047 const Configuration& config = context->GetConfiguration(); 00048 String tmp_dir = config["wordlist_cache"]; 00049 if(tmp_dir.empty()) 00050 tmp_dir = MIFLUZ_CACHE; 00051 name = strdup(namep); 00052 String filename = tmp_dir + String("/") + String(name); 00053 00054 int error; 00055 00056 if(verbose) 00057 fprintf(stderr, "WordListKey::Open: %s\n", (char*)filename); 00058 00059 if((error = CDB_db_env_create(&dbenv, 0)) != 0) { 00060 fprintf(stderr, "WordResults::Open db_env_create for %s failed %s\n", name, CDB_db_strerror(error)); 00061 return NOTOK; 00062 } 00063 00064 // 00065 // Environment 00066 // 00067 if((error = dbenv->open(dbenv, (char*)tmp_dir, DB_PRIVATE|DB_INIT_MPOOL|DB_CREATE, 0666)) != 0) { 00068 fprintf(stderr, "WordResults::Open dbenv->open(%s) failed: %s\n", (char*)tmp_dir, CDB_db_strerror(error)); 00069 return NOTOK; 00070 } 00071 00072 dbenv->set_errfile(dbenv, stderr); 00073 dbenv->set_errpfx(dbenv, "WordResults"); 00074 00075 // 00076 // Expire old result cache 00077 // 00078 { 00079 struct stat statbuf; 00080 if(stat((char*)filename, &statbuf) < 0) { 00081 if(errno != ENOENT) { 00082 fprintf(stderr, "WordResults::Open cannot stat %s:", (char*)filename); 00083 perror(""); 00084 return NOTOK; 00085 } 00086 } else { 00087 time_t now; 00088 if(time(&now) < 0) { 00089 fprintf(stderr, "WordResults::Open time failed while handling %s:", (char*)filename); 00090 perror(""); 00091 return NOTOK; 00092 } 00093 time_t timeout = config.Value("wordlist_cache_timeout"); 00094 // 00095 // Minimal value for timeout is 5 seconds 00096 // 00097 if(timeout < 5) timeout = 3600; 00098 if(now - statbuf.st_atime > timeout) { 00099 if(unlink((char*)filename) < 0) { 00100 fprintf(stderr, "WordResults::Open cannot unlink old cache file %s:", (char*)filename); 00101 perror(""); 00102 return NOTOK; 00103 } 00104 } 00105 } 00106 } 00107 00108 // 00109 // Variables list 00110 // 00111 if((error = CDB_db_create(&variables, dbenv, 0)) != 0) { 00112 fprintf(stderr, "WordResults::Open db_create(%s) variables failed: %s\n", name, CDB_db_strerror(error)); 00113 return NOTOK; 00114 } 00115 00116 if((error = variables->set_pagesize(variables, WORD_RESULT_PAGESIZE)) != 0) { 00117 fprintf(stderr, "WordResults::Open variables->set_pagesize(%d) failed: %s\n", WORD_RESULT_PAGESIZE, CDB_db_strerror(error)); 00118 return NOTOK; 00119 } 00120 00121 if((error = variables->open(variables, (char*)filename, "variables", DB_HASH, DB_CREATE, 0666)) != 0) { 00122 fprintf(stderr, "WordResults::Open variables->open(%s) failed: %s\n", name, CDB_db_strerror(error)); 00123 return NOTOK; 00124 } 00125 00126 if((error = variables->cursor(variables, 0, &variables_cursor, 0)) != 0) { 00127 fprintf(stderr, "WordResults::Open variables->cursor(%s) failed: %s\n", name, CDB_db_strerror(error)); 00128 return NOTOK; 00129 } 00130 00131 // 00132 // Sorted list 00133 // 00134 if((error = CDB_db_create(&sorted, dbenv, 0)) != 0) { 00135 fprintf(stderr, "WordResults::Open db_create(%s) sorted failed: %s\n", name, CDB_db_strerror(error)); 00136 return NOTOK; 00137 } 00138 00139 if((error = sorted->set_pagesize(sorted, WORD_RESULT_PAGESIZE)) != 0) { 00140 fprintf(stderr, "WordResults::Open sorted->set_pagesize(%d) failed: %s\n", WORD_RESULT_PAGESIZE, CDB_db_strerror(error)); 00141 return NOTOK; 00142 } 00143 00144 if((error = sorted->set_bt_compare(sorted, wordResults_cmp)) != 0) { 00145 fprintf(stderr, "WordResults::Open sorted->set_bt_compare(%s) failed: %s\n", name, CDB_db_strerror(error)); 00146 return NOTOK; 00147 } 00148 00149 if((error = sorted->open(sorted, (char*)filename, "sorted", DB_BTREE, DB_CREATE, 0666)) != 0) { 00150 fprintf(stderr, "WordResults::Open sorted->open(%s) failed: %s\n", name, CDB_db_strerror(error)); 00151 return NOTOK; 00152 } 00153 00154 if((error = sorted->cursor(sorted, 0, &sorted_cursor, 0)) != 0) { 00155 fprintf(stderr, "WordResults::Open sorted->cursor(%s) failed: %s\n", name, CDB_db_strerror(error)); 00156 return NOTOK; 00157 } 00158 00159 // 00160 // Uniq list 00161 // 00162 if((error = CDB_db_create(&uniq, dbenv, 0)) != 0) { 00163 fprintf(stderr, "WordResults::Open db_create(%s) uniq failed: %s\n", name, CDB_db_strerror(error)); 00164 return NOTOK; 00165 } 00166 00167 if((error = uniq->set_pagesize(uniq, WORD_RESULT_PAGESIZE)) != 0) { 00168 fprintf(stderr, "WordResults::Open uniq->set_pagesize(%d) failed: %s\n", WORD_RESULT_PAGESIZE, CDB_db_strerror(error)); 00169 return NOTOK; 00170 } 00171 00172 if((error = uniq->set_bt_compare(uniq, wordResults_cmp)) != 0) { 00173 fprintf(stderr, "WordResults::Open uniq->set_bt_compare(%s) failed: %s\n", name, CDB_db_strerror(error)); 00174 return NOTOK; 00175 } 00176 00177 if((error = uniq->open(uniq, (char*)filename, "uniq", DB_BTREE, DB_CREATE, 0666)) != 0) { 00178 fprintf(stderr, "WordResults::Open uniq->open(%s) failed: %s\n", name, CDB_db_strerror(error)); 00179 return NOTOK; 00180 } 00181 00182 if((error = uniq->cursor(uniq, 0, &uniq_cursor, 0)) != 0) { 00183 fprintf(stderr, "WordResults::Open uniq->cursor(%s) failed: %s\n", name, CDB_db_strerror(error)); 00184 return NOTOK; 00185 } 00186 00187 // 00188 // Ranked list 00189 // 00190 if((error = CDB_db_create(&ranked, dbenv, 0)) != 0) { 00191 fprintf(stderr, "WordResults::Open db_create(%s) ranked failed: %s\n", name, CDB_db_strerror(error)); 00192 return NOTOK; 00193 } 00194 00195 if((error = ranked->set_pagesize(ranked, WORD_RESULT_PAGESIZE)) != 0) { 00196 fprintf(stderr, "WordResults::Open ranked->set_pagesize(%d) failed: %s\n", WORD_RESULT_PAGESIZE, CDB_db_strerror(error)); 00197 return NOTOK; 00198 } 00199 00200 if((error = ranked->set_re_len(ranked, sizeof(WordKeyNum) * document_length)) != 0) { 00201 fprintf(stderr, "WordResults::Open ranked->set_re_len(%d) failed: %s\n", sizeof(WordKeyNum) * document_length, CDB_db_strerror(error)); 00202 return NOTOK; 00203 } 00204 00205 if((error = ranked->open(ranked, (char*)filename, "ranked", DB_RECNO, DB_CREATE, 0666)) != 0) { 00206 fprintf(stderr, "WordResults::Open ranked->open(%s) failed: %s\n", name, CDB_db_strerror(error)); 00207 return NOTOK; 00208 } 00209 00210 if((error = ranked->cursor(ranked, 0, &ranked_cursor, 0)) != 0) { 00211 fprintf(stderr, "WordResults::Open ranked->cursor(%s) failed: %s\n", name, CDB_db_strerror(error)); 00212 return NOTOK; 00213 } 00214 00215 // 00216 // Info list 00217 // 00218 if((error = CDB_db_create(&info, dbenv, 0)) != 0) { 00219 fprintf(stderr, "WordResults::Open db_create(%s) info failed: %s\n", name, CDB_db_strerror(error)); 00220 return NOTOK; 00221 } 00222 00223 if((error = info->set_pagesize(info, WORD_RESULT_PAGESIZE)) != 0) { 00224 fprintf(stderr, "WordResults::Open info->set_pagesize(%d) failed: %s\n", WORD_RESULT_PAGESIZE, CDB_db_strerror(error)); 00225 return NOTOK; 00226 } 00227 00228 if((error = info->open(info, (char*)filename, "info", DB_RECNO, DB_CREATE, 0666)) != 0) { 00229 fprintf(stderr, "WordResults::Open info->open(%s) failed: %s\n", name, CDB_db_strerror(error)); 00230 return NOTOK; 00231 } 00232 00233 if((error = info->cursor(info, 0, &info_cursor, 0)) != 0) { 00234 fprintf(stderr, "WordResults::Open info->cursor(%s) failed: %s\n", name, CDB_db_strerror(error)); 00235 return NOTOK; 00236 } 00237 00238 return OK; 00239 } 00240 00241 int WordResults::Close() 00242 { 00243 int error; 00244 00245 // 00246 // Variables list 00247 // 00248 if((error = variables_cursor->c_close(variables_cursor)) != 0) { 00249 fprintf(stderr, "WordResults::Close variables_cursor->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00250 } 00251 00252 if((error = variables->close(variables, 0)) != 0) { 00253 fprintf(stderr, "WordResults::Close variables->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00254 return NOTOK; 00255 } 00256 00257 // 00258 // Sorted list 00259 // 00260 if((error = sorted_cursor->c_close(sorted_cursor)) != 0) { 00261 fprintf(stderr, "WordResults::Close sorted_cursor->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00262 } 00263 00264 if((error = sorted->close(sorted, 0)) != 0) { 00265 fprintf(stderr, "WordResults::Close sorted->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00266 return NOTOK; 00267 } 00268 00269 // 00270 // Uniq list 00271 // 00272 if((error = uniq_cursor->c_close(uniq_cursor)) != 0) { 00273 fprintf(stderr, "WordResults::Close uniq_cursor->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00274 } 00275 00276 if((error = uniq->close(uniq, 0)) != 0) { 00277 fprintf(stderr, "WordResults::Close uniq->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00278 return NOTOK; 00279 } 00280 00281 // 00282 // Ranked list 00283 // 00284 if((error = ranked_cursor->c_close(ranked_cursor)) != 0) { 00285 fprintf(stderr, "WordResults::Close ranked_cursor->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00286 } 00287 00288 if((error = ranked->close(ranked, 0)) != 0) { 00289 fprintf(stderr, "WordResults::Close ranked->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00290 return NOTOK; 00291 } 00292 00293 // 00294 // Info list 00295 // 00296 if((error = info_cursor->c_close(info_cursor)) != 0) { 00297 fprintf(stderr, "WordResults::Close info_cursor->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00298 } 00299 00300 if((error = info->close(info, 0)) != 0) { 00301 fprintf(stderr, "WordResults::Close info->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00302 return NOTOK; 00303 } 00304 00305 // 00306 // Environment 00307 // 00308 if((error = dbenv->close(dbenv, 0)) != 0) { 00309 fprintf(stderr, "WordResults::Close dbenv->close(%s) failed: %s\n", name, CDB_db_strerror(error)); 00310 return NOTOK; 00311 } 00312 00313 free(name); 00314 00315 name = 0; 00316 sorted = 0; 00317 uniq = 0; 00318 ranked = 0; 00319 info = 0; 00320 dbenv = 0; 00321 return OK; 00322 } 00323 00324 int WordResults::KeySemantic(const WordKeySemantic& nkey_semantic) 00325 { 00326 key_semantic = nkey_semantic; 00327 00328 uniq_offset = key_semantic.Uniq(); 00329 document_offset = key_semantic.DocumentOffset(); 00330 document_length = key_semantic.DocumentLength(); 00331 00332 return OK; 00333 } 00334 00335 int WordResults::Filled() const 00336 { 00337 // 00338 // If reached the end of result list and no context was saved, it means 00339 // that this is the end of all possible results. 00340 // 00341 String context_in; 00342 GetContext(context_in); 00343 return context_in.empty(); 00344 } 00345 00346 int WordResults::Exists(const WordKey& key) const 00347 { 00348 DBT rkey; 00349 memset((void*)&rkey, '0円', sizeof(DBT)); 00350 rkey.data = (void*)(key.Values() + document_offset); 00351 rkey.size = sizeof(WordKeyNum) * document_length; 00352 rkey.app_private = (void*)document_length; 00353 00354 DBT rdata; 00355 db_recno_t recno; 00356 memset((void*)&rdata, '0円', sizeof(DBT)); 00357 rdata.data = (void*)&recno; 00358 rdata.size = sizeof(db_recno_t); 00359 00360 int error; 00361 if((error = sorted_cursor->c_get(sorted_cursor, &rkey, &rdata, DB_SET)) != 0) { 00362 if(error != DB_NOTFOUND) { 00363 fprintf(stderr, "WordResults::Exists sorted_cursor->c_get(%s) failed: %s\n", (char*)key.Get(), CDB_db_strerror(error)); 00364 } 00365 } 00366 00367 if(verbose) 00368 fprintf(stderr, "WordResults::Exists: %s %s\n", (char*)key.Get(), (error ? "was not found" : "was found")); 00369 00370 return error == 0; 00371 } 00372 00373 int WordResults::UniqExists(const WordKey& key) const 00374 { 00375 DBT rkey; 00376 memset((void*)&rkey, '0円', sizeof(DBT)); 00377 rkey.data = (void*)(key.Values() + uniq_offset); 00378 rkey.size = sizeof(WordKeyNum); 00379 rkey.app_private = (void*)1; 00380 00381 DBT rdata; 00382 db_recno_t recno; 00383 memset((void*)&rdata, '0円', sizeof(DBT)); 00384 rdata.data = (void*)&recno; 00385 rdata.size = sizeof(db_recno_t); 00386 00387 int error; 00388 if((error = uniq_cursor->c_get(uniq_cursor, &rkey, &rdata, DB_SET)) != 0) { 00389 if(error != DB_NOTFOUND) { 00390 fprintf(stderr, "WordResults::UniqExists uniq_cursor->c_get(%s) failed: %s\n", (char*)key.Get(), CDB_db_strerror(error)); 00391 } 00392 } 00393 00394 if(verbose) 00395 fprintf(stderr, "WordResults::UniqExists: %s %s\n", (char*)key.Get(), (error ? "was not found" : "was found")); 00396 00397 return error == 0; 00398 } 00399 00400 int WordResults::Get(WordMatches* matches, unsigned int length, unsigned int position) const 00401 { 00402 if(verbose) 00403 fprintf(stderr, "WordResults::Get: %d to %d\n", position, position + length); 00404 00405 int error; 00406 db_recno_t recno = position + 1; 00407 DBT rkey; 00408 DBT rdata; 00409 00410 memset((void*)&rkey, '0円', sizeof(DBT)); 00411 rkey.data = (void*)&recno; 00412 rkey.size = sizeof(db_recno_t); 00413 memset((void*)&rdata, '0円', sizeof(DBT)); 00414 00415 // 00416 // Ranked list 00417 // 00418 if((error = ranked_cursor->c_get(ranked_cursor, &rkey, &rdata, DB_SET)) != 0) { 00419 if(error != DB_NOTFOUND) { 00420 fprintf(stderr, "WordResults::Get ranked_cursor->c_get(%d, DB_SET) failed: %s\n", position, CDB_db_strerror(error)); 00421 } 00422 return WORD_WALK_END_CACHE; 00423 } 00424 // 00425 // Info list 00426 // 00427 if((error = info_cursor->c_get(info_cursor, &rkey, &rdata, DB_SET)) != 0) { 00428 if(error != DB_NOTFOUND) { 00429 fprintf(stderr, "WordResults::Get info_cursor->c_get(%d, DB_SET) failed: %s\n", position, CDB_db_strerror(error)); 00430 } 00431 return WORD_WALK_END_CACHE; 00432 } 00433 00434 if(verbose) 00435 fprintf(stderr, "WordResults::Get found match at position %d\n", position); 00436 00437 for(unsigned int i = 0; i < length && error == 0; i++) { 00438 WordMatch& match = *matches->matches[i]; 00439 00440 // 00441 // Ranked list 00442 // 00443 if((error = ranked_cursor->c_get(ranked_cursor, &rkey, &rdata, DB_CURRENT)) != 0) { 00444 fprintf(stderr, "WordResults::Get ranked_cursor->c_get(%d, DB_CURRENT) failed: %s\n", position, CDB_db_strerror(error)); 00445 return NOTOK; 00446 } 00447 00448 int* values = (int*)rdata.data; 00449 for(int j = document_offset; j < document_offset + document_length; j++) { 00450 match.match.Set(j, values[j - document_offset]); 00451 } 00452 00453 recno = *(db_recno_t*)(rkey.data); 00454 if(recno - 1 != position + i) { 00455 fprintf(stderr, "WordResults::Get ranked retrieved %s at position %d instead of expected %d\n", (char*)match.Get(), recno - 1, position + i); 00456 } 00457 00458 // 00459 // Info list 00460 // 00461 if((error = info_cursor->c_get(info_cursor, &rkey, &rdata, DB_CURRENT)) != 0) { 00462 fprintf(stderr, "WordResults::Get info_cursor->c_get(%d, DB_CURRENT) failed: %s\n", position, CDB_db_strerror(error)); 00463 return NOTOK; 00464 } 00465 00466 match.info.set((char*)rdata.data, (int)rdata.size); 00467 00468 recno = *(db_recno_t*)(rkey.data); 00469 if(recno - 1 != position + i) { 00470 fprintf(stderr, "WordResults::Get info retrieved %s at position %d instead of expected %d\n", (char*)match.Get(), recno - 1, position + i); 00471 } 00472 00473 // 00474 // Ranked list 00475 // 00476 if((error = ranked_cursor->c_get(ranked_cursor, &rkey, &rdata, DB_NEXT)) != 0) { 00477 if(error != DB_NOTFOUND) { 00478 fprintf(stderr, "WordResults::Get ranked_cursor->c_get(%d, DB_NEXT) failed: %s\n", recno, CDB_db_strerror(error)); 00479 return NOTOK; 00480 } 00481 } 00482 00483 // 00484 // Info list 00485 // 00486 if((error = info_cursor->c_get(info_cursor, &rkey, &rdata, DB_NEXT)) != 0) { 00487 if(error != DB_NOTFOUND) { 00488 fprintf(stderr, "WordResults::Get info_cursor->c_get(%d, DB_NEXT) failed: %s\n", recno, CDB_db_strerror(error)); 00489 return NOTOK; 00490 } 00491 } 00492 00493 if(verbose) 00494 fprintf(stderr, "WordResults::Get retrieved %s at position %d\n", (char*)match.Get(), position + i); 00495 00496 match.valid = 1; 00497 matches->length++; 00498 } 00499 00500 int ret = OK; 00501 // 00502 // If reached the end of result list and no context was saved, it means 00503 // that this is the end of all possible results. 00504 // 00505 if(error == DB_NOTFOUND) { 00506 ret = Filled() ? WORD_WALK_ATEND : WORD_WALK_END_CACHE; 00507 } 00508 00509 return ret; 00510 } 00511 00512 int WordResults::Put(const WordMatch& match, unsigned int position) 00513 { 00514 if(verbose) 00515 fprintf(stderr, "WordResults::Put: %s at %d\n", (char*)match.Get(), position); 00516 00517 int error; 00518 db_recno_t recno = 0; 00519 DBT rkey; 00520 DBT rdata; 00521 00522 // 00523 // Ranked list 00524 // 00525 memset((void*)&rkey, '0円', sizeof(DBT)); 00526 memset((void*)&rdata, '0円', sizeof(DBT)); 00527 rdata.data = (void*)(match.match.Values() + document_offset); 00528 rdata.size = sizeof(WordKeyNum) * document_length; 00529 00530 if((error = ranked->put(ranked, 0, &rkey, &rdata, DB_APPEND)) != 0) { 00531 fprintf(stderr, "WordResults::Put ranked->put(%s) failed: %s\n", (char*)match.Get(), CDB_db_strerror(error)); 00532 return NOTOK; 00533 } 00534 00535 recno = *(db_recno_t*)(rkey.data); 00536 if(recno - 1 != position) { 00537 fprintf(stderr, "WordResults::Put ranked->put(%s) inserted at position %d instead of expected %d\n", (char*)match.Get(), recno - 1, position); 00538 return NOTOK; 00539 } 00540 00541 // 00542 // Info list 00543 // 00544 memset((void*)&rkey, '0円', sizeof(DBT)); 00545 memset((void*)&rdata, '0円', sizeof(DBT)); 00546 rdata.data = (void*)match.info.get(); 00547 rdata.size = match.info.length(); 00548 00549 if((error = info->put(info, 0, &rkey, &rdata, DB_APPEND)) != 0) { 00550 fprintf(stderr, "WordResults::Put info->put(%s) failed: %s\n", (char*)match.Get(), CDB_db_strerror(error)); 00551 return NOTOK; 00552 } 00553 00554 recno = *(db_recno_t*)(rkey.data); 00555 if(recno - 1 != position) { 00556 fprintf(stderr, "WordResults::Put info->put(%s) inserted at position %d instead of expected %d\n", (char*)match.Get(), recno - 1, position); 00557 return NOTOK; 00558 } 00559 00560 // 00561 // Sorted list 00562 // 00563 memset((void*)&rkey, '0円', sizeof(DBT)); 00564 rkey.data = (void*)(match.match.Values() + document_offset); 00565 rkey.size = sizeof(WordKeyNum) * document_length; 00566 rkey.app_private = (void*)document_length; 00567 00568 memset((void*)&rdata, '0円', sizeof(DBT)); 00569 rdata.data = (void*)&recno; 00570 rdata.size = sizeof(db_recno_t); 00571 00572 if((error = sorted_cursor->c_put(sorted_cursor, &rkey, &rdata, DB_KEYLAST)) != 0) { 00573 fprintf(stderr, "WordResults::Put sorted_cursor->c_put(%s) failed: %s\n", (char*)match.Get(), CDB_db_strerror(error)); 00574 return NOTOK; 00575 } 00576 00577 // 00578 // Uniq list 00579 // 00580 if(uniq_offset) { 00581 memset((void*)&rkey, '0円', sizeof(DBT)); 00582 rkey.data = (void*)(match.match.Values() + uniq_offset); 00583 rkey.size = sizeof(WordKeyNum); 00584 rkey.app_private = (void*)1; 00585 00586 memset((void*)&rdata, '0円', sizeof(DBT)); 00587 rdata.data = (void*)&recno; 00588 rdata.size = sizeof(db_recno_t); 00589 00590 if((error = uniq_cursor->c_put(uniq_cursor, &rkey, &rdata, DB_KEYLAST)) != 0) { 00591 fprintf(stderr, "WordResults::Put uniq_cursor->c_put(%s) failed: %s\n", (char*)match.Get(), CDB_db_strerror(error)); 00592 return NOTOK; 00593 } 00594 } 00595 00596 return OK; 00597 } 00598 00599 int WordResults::PutContext(const String& context_out) 00600 { 00601 if(verbose) 00602 fprintf(stderr, "WordResults::PutContext: %s\n", (const char*)context_out); 00603 00604 DBT rkey; 00605 DBT rdata; 00606 int error; 00607 00608 memset((void*)&rkey, '0円', sizeof(DBT)); 00609 rkey.data = (void*)"context"; 00610 rkey.size = strlen((char*)rkey.data); 00611 00612 memset((void*)&rdata, '0円', sizeof(DBT)); 00613 rdata.data = (void*)context_out.get(); 00614 rdata.size = context_out.length(); 00615 00616 if((error = variables_cursor->c_put(variables_cursor, &rkey, &rdata, DB_KEYFIRST)) != 0) { 00617 fprintf(stderr, "WordResults::PutContext variables_cursor->c_put(%s) failed: %s\n", (const char*)context_out, CDB_db_strerror(error)); 00618 return NOTOK; 00619 } 00620 00621 return OK; 00622 } 00623 00624 int WordResults::GetContext(String& context_in) const 00625 { 00626 if(verbose) 00627 fprintf(stderr, "WordResults::GetContext:\n"); 00628 00629 context_in.trunc(); 00630 00631 DBT rkey; 00632 DBT rdata; 00633 00634 memset((void*)&rkey, '0円', sizeof(DBT)); 00635 rkey.data = (void*)"context"; 00636 rkey.size = strlen((char*)rkey.data); 00637 00638 memset((void*)&rdata, '0円', sizeof(DBT)); 00639 00640 int error; 00641 if((error = variables_cursor->c_get(variables_cursor, &rkey, &rdata, DB_SET)) != 0) { 00642 if(error != DB_NOTFOUND) { 00643 fprintf(stderr, "WordResults::GetContext variables_cursor->c_get(context) failed: %s\n", CDB_db_strerror(error)); 00644 return NOTOK; 00645 } 00646 } 00647 00648 context_in.set((char*)rdata.data, (unsigned int)rdata.size); 00649 00650 return OK; 00651 } 00652 00653 int WordResults::PutMatchesTotal(unsigned int matches_total) 00654 { 00655 if(verbose) 00656 fprintf(stderr, "WordResults::PutMatchesTotal: %d\n", matches_total); 00657 00658 DBT rkey; 00659 DBT rdata; 00660 int error; 00661 00662 memset((void*)&rkey, '0円', sizeof(DBT)); 00663 rkey.data = (void*)"matches_total"; 00664 rkey.size = strlen((char*)rkey.data); 00665 00666 memset((void*)&rdata, '0円', sizeof(DBT)); 00667 rdata.data = (void*)&matches_total; 00668 rdata.size = sizeof(unsigned int); 00669 00670 if((error = variables_cursor->c_put(variables_cursor, &rkey, &rdata, DB_KEYFIRST)) != 0) { 00671 fprintf(stderr, "WordResults::PutMatchesTotal: variables_cursor->c_put(%d) failed: %s\n", matches_total, CDB_db_strerror(error)); 00672 return NOTOK; 00673 } 00674 00675 return OK; 00676 } 00677 00678 int WordResults::GetMatchesTotal(unsigned int& matches_total) const 00679 { 00680 if(verbose) 00681 fprintf(stderr, "WordResults::GetMatchesTotal:\n"); 00682 00683 matches_total = 0; 00684 00685 DBT rkey; 00686 DBT rdata; 00687 00688 memset((void*)&rkey, '0円', sizeof(DBT)); 00689 rkey.data = (void*)"matches_total"; 00690 rkey.size = strlen((char*)rkey.data); 00691 00692 memset((void*)&rdata, '0円', sizeof(DBT)); 00693 00694 int error; 00695 if((error = variables_cursor->c_get(variables_cursor, &rkey, &rdata, DB_SET)) != 0) { 00696 if(error != DB_NOTFOUND) { 00697 fprintf(stderr, "WordResults::GetMatchesTotal variables_cursor->c_get(matches_total) failed: %s\n", CDB_db_strerror(error)); 00698 return NOTOK; 00699 } 00700 } 00701 00702 if(error == 0) { 00703 memcpy((char*)&matches_total, (char*)rdata.data, sizeof(unsigned int)); 00704 } else { 00705 matches_total = 0; 00706 } 00707 00708 return OK; 00709 } 00710 00711 int WordResults::Count(unsigned int& count) const 00712 { 00713 int error; 00714 DBT rkey; 00715 DBT rdata; 00716 00717 memset((void*)&rkey, '0円', sizeof(DBT)); 00718 memset((void*)&rdata, '0円', sizeof(DBT)); 00719 00720 if((error = ranked_cursor->c_get(ranked_cursor, &rkey, &rdata, DB_LAST)) != 0) { 00721 if(error != DB_NOTFOUND) { 00722 fprintf(stderr, "WordResults::Count ranked_cursor->c_get(DB_LAST) failed: %s\n", CDB_db_strerror(error)); 00723 return NOTOK; 00724 } 00725 count = 0; 00726 } else { 00727 count = *(unsigned int*)(rkey.data); 00728 } 00729 00730 if(verbose) 00731 fprintf(stderr, "WordResults::Count %d\n", count); 00732 00733 return OK; 00734 }