Changeset 241
- Timestamp:
- 03/16/07 23:10:00 (1 year ago)
- Files:
-
- 06/libkombilo-branches/hash_center/cpptest.cpp (modified) (5 diffs)
- 06/libkombilo-branches/hash_center/process.py (modified) (4 diffs)
- 06/libkombilo-branches/hash_center/search.cpp (modified) (32 diffs)
- 06/libkombilo-branches/hash_center/search.h (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
06/libkombilo-branches/hash_center/cpptest.cpp
r240 r241 9 9 int main(int argc, char** argv) { 10 10 // ----------------- parse command line arguments --------------------------------- 11 int algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER ;11 int algos = ALGO_FINALPOS | ALGO_MOVELIST | ALGO_HASH_FULL | ALGO_HASH_CORNER | ALGO_HASH_CENTER; 12 12 bool process = false; 13 13 for(int i=1; i<argc; i++) { … … 29 29 gl.start_processing(); 30 30 directory_iterator end_itr; 31 // string path = "/home/ug/go/kombilo/06/ center_hashes/libkombilo";31 // string path = "/home/ug/go/kombilo/06/hash_center"; 32 32 // string path = "/home/ug/go/gtl/reviews"; 33 33 string path = "/home/ug/go/gogod06/2000"; … … 70 70 // For example, CORNER_NW_PATTERN corresponds to (0,0,0,0) 71 71 // Pattern p(2,3,4,6, 19, 3, 3, ".X.XXXXOX", vector<MoveNC>()); 72 73 // Pattern p(CORNER_NW_PATTERN,19,8,8,"...................X......X.......XO......OO...................."); 72 73 // Pattern p(CORNER_NW_PATTERN,19,8,8, 74 // "........" 75 // "........" 76 // "...X...." 77 // "........" 78 // "...O...." 79 // "........" 80 // "........" 81 // "........"); 82 Pattern p(CORNER_NW_PATTERN,19,7,8, 83 "......." 84 "......." 85 "...O..." 86 "......." 87 "......." 88 "......." 89 "......." 90 "......."); 74 91 // Pattern p(CORNER_NW_PATTERN,19,7,7,".................X.....X......XO.....OO.........."); 75 92 // Pattern p(CORNER_NW_PATTERN,19,7,7,".......................X........................."); 76 93 77 94 // gl.gisearch("pw = 'Hane Naoki'"); 78 Pattern p(CENTER_PATTERN, 19, 3, 5, ".X..OX.OX.OXOXO");95 // Pattern p(CENTER_PATTERN, 19, 3, 5, ".X..OX.OX.OXOXO"); 79 96 // vector<MoveNC> contList; 80 97 // contList.push_back(MoveNC(6,15,'X')); … … 88 105 // -------------------- set up search options ---------------------------------- 89 106 SearchOptions so; 107 so.algos = algos; 108 // so.fixedColor = true; 90 109 // so.trustHashFull = true; 91 110 // SearchOptions so(0,0,50); // use move limit … … 94 113 95 114 // -------------------- do pattern search -------------------------------------- 96 //gl.search(p, &so);115 gl.search(p, &so); 97 116 98 117 // ------------------- print some information about current list of games ------------ 99 //printf("num games: %d, num hits: %d\n", gl.size(), gl.numHits());118 printf("num games: %d, num hits: %d\n", gl.size(), gl.numHits()); 100 119 // vector<string> res = gl.currentEntriesAsStrings(); 101 120 // for(vector<string>::iterator it = res.begin(); it != res.end(); it++) 102 121 // printf("%s\n", it->c_str()); 103 //for(int i=0; i<gl.size(); i++) printf("%s\n", gl.currentEntryAsString(i).c_str());122 // for(int i=0; i<gl.size(); i++) printf("%s\n", gl.currentEntryAsString(i).c_str()); 104 123 105 124 // ------------------- print some statistics ------------------------------------------ 106 //printf("Search pattern:\n");107 //printf("%s\n", p.printPattern().c_str());108 //printf("Continuations:\n");109 //for(int y=0; y<p.sizeY; y++) {110 //for(int x=0; x<p.sizeX; x++) {111 //printf("%c", gl.lookupLabel(x,y));112 //}113 //printf("\n");114 //}115 //printf("\n");116 //printf("Statistics:\n");117 //printf("num hits: %d, num switched: %d, B wins: %d, W wins: %d\n", gl.num_hits, gl.num_switched, gl.Bwins, gl.Wwins);125 printf("Search pattern:\n"); 126 printf("%s\n", p.printPattern().c_str()); 127 printf("Continuations:\n"); 128 for(int y=0; y<p.sizeY; y++) { 129 for(int x=0; x<p.sizeX; x++) { 130 printf("%c", gl.lookupLabel(x,y)); 131 } 132 printf("\n"); 133 } 134 printf("\n"); 135 printf("Statistics:\n"); 136 printf("num hits: %d, num switched: %d, B wins: %d, W wins: %d\n", gl.num_hits, gl.num_switched, gl.Bwins, gl.Wwins); 118 137 119 //printf("Continuation | Black ( B wins / W wins ) | White (B wins / W wins) |\n");120 //for(int y=0; y<p.sizeY; y++) {121 //for(int x=0; x<p.sizeX; x++) {122 //if (gl.lookupLabel(x,y) != '.') {123 //Continuation cont = gl.lookupContinuation(x,y);124 //printf(" %c | %3d[%3d] ( %3d / %3d ) | %3d[%3d] ( %3d / %3d) | %1.1f / %1.1f \n",125 //gl.lookupLabel(x,y), cont.B, cont.tB, cont.wB, cont.lB, cont.W, cont.tW, cont.wW, cont.lW,126 //cont.wW*100.0/cont.W, cont.wB*100.0/cont.B);127 //}128 //}129 //}138 printf("Continuation | Black ( B wins / W wins ) | White (B wins / W wins) |\n"); 139 for(int y=0; y<p.sizeY; y++) { 140 for(int x=0; x<p.sizeX; x++) { 141 if (gl.lookupLabel(x,y) != '.') { 142 Continuation cont = gl.lookupContinuation(x,y); 143 printf(" %c | %3d[%3d] ( %3d / %3d ) | %3d[%3d] ( %3d / %3d) | %1.1f / %1.1f \n", 144 gl.lookupLabel(x,y), cont.B, cont.tB, cont.wB, cont.lB, cont.W, cont.tW, cont.wW, cont.lW, 145 cont.wW*100.0/cont.W, cont.wB*100.0/cont.B); 146 } 147 } 148 } 130 149 131 150 // ------------------- check for duplicates --------------------------------- 06/libkombilo-branches/hash_center/process.py
r240 r241 11 11 try: 12 12 os.system('rm t1.db*') 13 pass 13 14 except: 14 15 pass … … 24 25 # pop.rootNodeTags = 'PW,PB,RE,DT' 25 26 pop.sgfInDB = False 26 gl = GameList('t1.db', 'id', '', pop, 80)27 gl = GameList('t1.db', 'id', '', pop, 150) 27 28 except DBError: 28 29 print 'Database error' … … 50 51 51 52 # filelist = glob.glob('./*.sgf') 52 #filelist = glob.glob('/home/ug/go/gogod06/*/*.sgf')53 filelist = glob.glob('/home/ug/go/KGS/*/*.sgf')53 filelist = glob.glob('/home/ug/go/gogod06/*/*.sgf') 54 # filelist = glob.glob('/home/ug/go/KGS/*/*.sgf') 54 55 # filelist = glob.glob('/home/ug/go/KGS2005/*.sgf') 55 56 … … 57 58 process(filelist) 58 59 59 gl = GameList("t1.db", "id", "[[filename.]], ")60 # gl = GameList("t1.db", "id", "[[filename.]], ") 60 61 61 p = Pattern(CENTER_PATTERN, 19, 3, 5, ".X..OX.OX.OXOXO")62 so = SearchOptions()62 # p = Pattern(CENTER_PATTERN, 19, 3, 5, ".X..OX.OX.OXOXO") 63 # so = SearchOptions() 63 64 64 gl.reset()65 gl.search(p, so)65 # gl.reset() 66 # gl.search(p, so) 66 67 67 for i in range(gl.size())[-10:]:68 print gl.currentEntryAsString(i)68 # for i in range(gl.size())[-10:]: 69 # print gl.currentEntryAsString(i) 69 70 70 71 06/libkombilo-branches/hash_center/search.cpp
r240 r241 37 37 using std::make_pair; 38 38 using std::stack; 39 using std::set; 39 40 40 41 #if defined(_MSC_VER) … … 300 301 Pattern::Pattern(int le, int ri, int to, int bo, int BOARDSIZE, int sX, int sY, char* iPos, const vector<MoveNC>& CONTLIST, char* CONTLABELS) throw(PatternError) { 301 302 // check whether anchor rectangle is valid 302 if (le < 0 || ri+sX > BOARDSIZE || to < 0 || bo+sY > BOARDSIZE || ri < le || bo < to) throw PatternError(); 303 if ((le < 0) || ri+sX > BOARDSIZE || to < 0 || bo+sY > BOARDSIZE || ri < le || bo < to) 304 throw PatternError(); 303 305 304 306 flip = 0; … … 466 468 } 467 469 468 Pattern* pNew =new Pattern(newLeft, newRight, newTop, newBottom, boardsize, newSizeX, newSizeY,469 newInitialPos, newContList);470 Pattern* pNew =new Pattern(newLeft, newRight, newTop, newBottom, boardsize, 471 newSizeX, newSizeY, newInitialPos, newContList); 470 472 471 473 pNew->flip = f; 472 474 if (CS) pNew->colorSwitch = 1; 475 else pNew->colorSwitch = 0; 473 476 delete [] newInitialPos; 474 477 return *pNew; … … 520 523 521 524 int Pattern::flipsX(int i, int x, int y, int XX, int YY) { 522 if (i==0) return x; 523 if (i==1) return XX-x; 524 if (i==2) return x; 525 if (i==3) return XX-x; 526 if (i==4) return y; 527 if (i==5) return YY-y; 528 if (i==6) return y; 529 if (i==7) return YY-y; 525 if (i==0) return x; // id 526 if (i==1) return XX-x; // mirror vertically 527 if (i==2) return x; // mirror horizontally 528 if (i==3) return XX-x; // rotate by 180 deg 529 if (i==4) return y; // mirror wrt main diagonal (\) 530 if (i==5) return YY-y; // rotate by -90 deg 531 if (i==6) return y; // rotate by 90 deg 532 if (i==7) return YY-y; // mirror wrt second diagonal (/) 530 533 return -1; 531 534 } … … 582 585 583 586 void PatternList::patternList() { 584 587 585 588 vector<Pattern> lCS; 586 589 vector<pair<int,int> > sy; 587 int boardsize = pattern.boardsize;588 590 589 591 for(int f = 0; f < 8; f++) { … … 600 602 } 601 603 if (foundNewPattern) { 604 printf("new p: %s\n", pNew.printPattern().c_str()); 602 605 flipTable[f] = data.size(); 603 606 data.push_back(pNew); … … 607 610 608 611 if (nextMove || !fixedColor) { // need to consider CS'ed patterns 609 Pattern pNew1 = pattern.apply_flip(f, 1);612 Pattern pNew1 = pattern.apply_flip(f, true); 610 613 611 614 if (!fixedColor) { … … 2201 2204 } 2202 2205 2206 HashhitCS::HashhitCS(int GAMEID, int POS, int ORI, bool CS) { 2207 gameid = GAMEID; 2208 position = POS + (ORI << 16); 2209 cs = CS; 2210 } 2211 2203 2212 HashhitCS::HashhitCS(int GAMEID, int POSITION, bool CS) { 2204 2213 gameid = GAMEID; … … 2207 2216 } 2208 2217 2218 bool HashhitCS::operator==(const HashhitCS& hcs) { 2219 if (gameid != hcs.gameid) return false; 2220 if (position != hcs.position) return false; 2221 if (cs != hcs.cs) return false; 2222 return true; 2223 } 2224 2225 int HashhitCS::get_pos() { 2226 return position % (1<<16); 2227 } 2228 2229 int HashhitCS::get_ori() { 2230 return position / (1<<16); 2231 } 2232 2209 2233 bool cmp_HashhitCS(const HashhitCS* a, const HashhitCS* b) { 2234 if (a->gameid == b->gameid) { 2235 if (a->position == b->position) { 2236 if (!a->cs && b->cs) return true; 2237 else return false; 2238 } else return a->position < b->position; 2239 } 2210 2240 return a->gameid < b->gameid; 2211 2241 } … … 2535 2565 // ----------------------------------------------------------------------------------- 2536 2566 2537 HashQuery::HashQuery(std::string SQL, Pattern* p0, int OFF0, int FLIP0, hashtype HASHCODE0, Pattern* p1, int OFF1, int FLIP1) { 2567 HashQuery::HashQuery() { 2568 sql = ""; 2569 pl0 = 0; 2570 offset0 = 0; 2571 pl1 = 0; 2572 flip0 = 0; 2573 flip1 = 0; 2574 hashCode0 = NOT_HASHABLE; 2575 } 2576 2577 HashQuery::HashQuery(std::string SQL, Pattern* p0, int OFF0X, int OFF0Y, int FLIP0, hashtype HASHCODE0, Pattern* p1, int FLIP1) { 2538 2578 sql = SQL; 2539 if (p0) pl0 = new PatternList(*p0,1,0); 2540 else pl0 = 0; 2541 if (p1) pl1 = new PatternList(*p1,1,0); 2542 else pl1 = 0; 2543 offset0 = OFF0; 2544 offset1 = OFF1; 2579 if (p0) { 2580 printf("use \n%s\n", p0->printPattern().c_str()); 2581 pl0 = new PatternList(*p0,1,0); 2582 printf("pl size %d\n", pl0->size()); 2583 offset0 = OFF0X + p0->sizeX * OFF0Y; 2584 delete p0; 2585 } else { 2586 pl0 = 0; 2587 offset0 = 0; 2588 } 2589 if (p1) { 2590 pl1 = new PatternList(*p1,1,0); 2591 delete p1; 2592 } else { 2593 pl1 = 0; 2594 } 2545 2595 flip0 = FLIP0; 2546 2596 flip1 = FLIP1; … … 2553 2603 } 2554 2604 2555 2556 CompleteHashKey::CompleteHashKey(hashtype HASHCODE, int OFFSETX, int OFFSETY, int INDEX) { 2605 int HashQuery::get_offX() { 2606 return offset0 % pl0->pattern.sizeX; 2607 } 2608 2609 int HashQuery::get_offY() { 2610 return offset0 / pl0->pattern.sizeX; 2611 2612 } 2613 2614 CompleteHashKey::CompleteHashKey(hashtype HASHCODE, int INDEX) { 2557 2615 hashCode = HASHCODE; 2558 offsetX = OFFSETX;2559 offsetY = OFFSETY;2616 // offsetX = OFFSETX; 2617 // offsetY = OFFSETY; 2560 2618 index = INDEX; 2561 2619 } … … 2563 2621 CompleteHashKey::CompleteHashKey() { 2564 2622 hashCode = NOT_HASHABLE; 2565 offsetX = 0;2566 offsetY = 0;2623 // offsetX = 0; 2624 // offsetY = 0; 2567 2625 index = -1; 2568 2626 } 2569 2627 2628 HashCTREntry::HashCTREntry() { 2629 } 2630 2631 HashCTREntry::HashCTREntry(unsigned char* c, int l, bool cs) { 2632 // format of c: 2633 // 4 bytes: game_id, 2634 // 2 bytes: position, 2635 // 1 byte: orientation 2636 add(c, l, cs, false); 2637 } 2638 2639 HashCTREntry::~HashCTREntry() { 2640 for(vector<HashhitCS* >::iterator it = data.begin(); it != data.end(); it++) 2641 delete *it; 2642 } 2643 2644 void HashCTREntry::add(unsigned char* c, int l, bool cs, bool do_sort) { 2645 for(int i = 0; i < l/7; i++) { 2646 int gameid = *(int*)(c+7*i); 2647 int ori = c[7*i+6]; 2648 int pos = (c[7*i+4] << 8) + c[7*i+5]; 2649 data.push_back(new HashhitCS(gameid, pos, ori, cs)); 2650 // printf("HashCTREntry::add 0 gid: %d, ori: %d, pos: %d, l: %d\n", gameid, ori, pos, data.size()); 2651 } 2652 if (do_sort) sort(data.begin(), data.end(), cmp_HashhitCS); 2653 } 2654 2655 void HashCTREntry::add(int gameid, int pos, char ori, bool cs) { 2656 data.push_back(new HashhitCS(gameid, pos, ori, cs)); 2657 // printf("HashCTREntry::add 1 gid: %d, ori: %d, pos: %d,l: %d\n", gameid, ori, pos, data.size()); 2658 if (data.size() > 1) sort(data.begin(), data.end(), cmp_HashhitCS); 2659 } 2660 2661 void HashCTREntry::add(int gameid, int position, bool cs) { 2662 data.push_back(new HashhitCS(gameid, position, cs)); 2663 // printf("HashCTREntry::add 2 gid: %d, position: %d, l:%d\n", gameid, position, data.size()); 2664 if (data.size() > 1) sort(data.begin(), data.end(), cmp_HashhitCS); 2665 } 2666 2667 char* HashCTREntry::to_charp() { 2668 // printf("to charp\n"); 2669 char* c = new char[7*data.size()]; 2670 unsigned int i=0; 2671 for(vector<HashhitCS* >::iterator it = data.begin(); it != data.end(); it++) { 2672 // printf("loop\n"); 2673 *(int*)(c+7*i) = (*it)->gameid; 2674 c[7*i+4] = (*it)->get_pos() / 256; 2675 c[7*i+5] = (*it)->get_pos() % 256; 2676 c[7*i+6] = (*it)->get_ori(); 2677 i++; 2678 } 2679 return c; 2680 } 2681 2682 int HashCTREntry::get_length() { 2683 // printf("get length %d\n", data.size()); 2684 return 7*data.size(); 2685 } 2570 2686 2571 2687 Algo_hash::Algo_hash(int bsize, const string& DBNAMEEXT, int MAXNUMSTONES) : Algorithm(bsize) { … … 2585 2701 2586 2702 int Algo_hash::insert_hash(hashtype hashCode, int pos) { 2587 hash_vector.push_back(make_pair(hashCode, pos)); 2703 hash_vector.insert(make_pair(hashCode, pos)); 2704 // printf("insert %lld, %d, %d\n", hashCode, pos/(1<<16), pos%(1<<16)); 2588 2705 return 0; 2589 2706 } … … 2591 2708 int Algo_hash::insert_all_hashes() { 2592 2709 // printf("insert all hashes %d\n", hash_vector.size()); 2710 int rc; 2593 2711 char sql[200]; 2594 sprintf(sql, "insert into algo_hash_%d_%s (hash, gameid, position) values (?,?,?);", boardsize, dbnameext.c_str()); 2595 sqlite3_stmt *ppStmt=0; 2596 int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 2597 if (rc != SQLITE_OK || ppStmt==0) return rc; 2598 rc = sqlite3_bind_int(ppStmt, 2, gid); 2599 if (rc != SQLITE_OK) return rc; 2600 for(vector<pair<hashtype, int> >::iterator it = hash_vector.begin(); it != hash_vector.end(); it++) { 2601 // printf("insert %d %d\n", it->first, it->second); 2602 rc = sqlite3_bind_int64(ppStmt, 1, it->first); 2603 if (rc != SQLITE_OK) return rc; 2604 rc = sqlite3_bind_int(ppStmt, 3, it->second); 2605 if (rc != SQLITE_OK) return rc; 2606 rc = sqlite3_step(ppStmt); 2607 if (rc != SQLITE_DONE) return rc; 2608 rc = sqlite3_reset(ppStmt); 2609 if (rc != SQLITE_OK) return rc; 2610 } 2611 rc = sqlite3_finalize(ppStmt); 2612 if (rc != SQLITE_OK) return rc; 2712 2713 if (!updStmt) { 2714 // printf("update algo_hash_%d_%s set data = ? where hash = ?;\n", boardsize, dbnameext.c_str()); 2715 sprintf(sql, "update algo_hash_%d_%s set data = ? where hash = ?;", boardsize, dbnameext.c_str()); 2716 int rc = sqlite3_prepare(db, sql, -1, &updStmt, 0); 2717 if (rc != SQLITE_OK || updStmt==0) printf("error 1: %d\n", rc); // return rc; 2718 // else printf("ok 1\n"); 2719 // printf("insert into algo_hash_%d_%s (hash, data) values (?,?);\n", boardsize, dbnameext.c_str()); 2720 } 2721 if (!insStmt) { 2722 sprintf(sql, "insert into algo_hash_%d_%s (hash, data) values (?,?);", boardsize, dbnameext.c_str()); 2723 insStmt=0; 2724 rc = sqlite3_prepare(db, sql, -1, &insStmt, 0); 2725 if (rc != SQLITE_OK || insStmt==0) printf("error 2: %d\n", rc); // return rc; 2726 // else printf("ok 2\n"); 2727 } 2728 if (!selStmt) { 2729 // printf("select data from algo_hash_%d_%s where hash = ?\n", boardsize, dbnameext.c_str()); 2730 sprintf(sql, "select data from algo_hash_%d_%s where hash = ?", boardsize, dbnameext.c_str()); 2731 rc = sqlite3_prepare(db, sql, -1, &selStmt, 0); 2732 if (rc != SQLITE_OK || selStmt==0) printf("error 3: %d\n", rc); // return rc; 2733 // else printf("ok 3\n"); 2734 } 2735 2736 for(set<pair<hashtype, int> >::iterator it = hash_vector.begin(); it != hash_vector.end(); it++) { 2737 // printf("enter loop\n"); 2738 HashCTREntry* he = 0; 2739 rc = sqlite3_bind_int64(selStmt, 1, it->first); 2740 if (rc != SQLITE_OK) printf("error 4a: %d\n", rc); // return rc; 2741 rc = sqlite3_step(selStmt); 2742 if (rc != SQLITE_DONE && rc != SQLITE_ROW) printf("error 4: %d\n", rc); // throw DBError(); 2743 // else printf("ok 4\n"); 2744 if (rc == SQLITE_ROW) { 2745 // printf("update %lld\n", it->first); 2746 he = new HashCTREntry((unsigned char*)sqlite3_column_blob(selStmt, 0), sqlite3_column_bytes(selStmt, 0)); 2747 // if (he->get_length() != sqlite3_column_bytes(selStmt, 0)) 2748 // printf("ouch %d %d\n", he->get_length(), sqlite3_column_bytes(selStmt, 0)); 2749 he->add(gid, it->second); 2750 char* he_charp = he->to_charp(); 2751 rc = sqlite3_bind_blob(updStmt, 1, he_charp, he->get_length(), SQLITE_TRANSIENT); 2752 if (rc != SQLITE_OK) printf("error 5: %d\n", rc); // return rc; 2753 // else printf("ok 5\n"); 2754 delete [] he_charp; 2755 rc = sqlite3_bind_int64(updStmt, 2, it->first); 2756 if (rc != SQLITE_OK) printf("error 6: %d\n", rc); // return rc; 2757 // else printf("ok 6\n"); 2758 rc = sqlite3_step(updStmt); 2759 if (rc != SQLITE_DONE) printf("error 7: %d\n", rc); // return rc; 2760 // else printf("ok 7\n"); 2761 rc = sqlite3_reset(updStmt); 2762 if (rc != SQLITE_OK) printf("error 8: %d\n", rc); // return rc; 2763 // else printf("ok 8\n"); 2764 // sqlite3_reset(selStmt); 2765 // rc = sqlite3_step(selStmt); 2766 // printf("new length %d\n", sqlite3_column_bytes(selStmt, 0)); 2767 delete he; 2768 } else { 2769 // printf("insert %lld\n", it->first); 2770 he = new HashCTREntry(); 2771 he->add(gid, it->second); 2772 rc = sqlite3_bind_int64(insStmt, 1, it->first); 2773 if (rc != SQLITE_OK) printf("error 9: %d\n", rc); // return rc; 2774 // else printf("ok 9\n"); 2775 char* he_charp = he->to_charp(); 2776 rc = sqlite3_bind_blob(insStmt, 2, he_charp, he->get_length(), SQLITE_TRANSIENT); 2777 if (rc != SQLITE_OK) printf("error 10: %d\n", rc); // return rc; 2778 // else printf("ok 10\n"); 2779 delete [] he_charp; 2780 rc = sqlite3_step(insStmt); 2781 if (rc != SQLITE_DONE) printf("error 11: %d\n", rc); // return rc; 2782 // else printf("ok 11\n"); 2783 rc = sqlite3_reset(insStmt); 2784 if (rc != SQLITE_OK) printf("error 12: %d\n", rc); // return rc; 2785 // else printf("ok 12\n"); 2786 // sqlite3_reset(selStmt); 2787 // rc = sqlite3_step(selStmt); 2788 // printf("new length %d\n", sqlite3_column_bytes(selStmt, 0)); 2789 delete he; 2790 } 2791 rc = sqlite3_reset(selStmt); 2792 if (rc != SQLITE_OK) printf("error 13: %d\n", rc); // throw DBError(); 2793 // else printf("ok 13\n"); 2794 } 2613 2795 return 0; // success 2614 2796 } … … 2618 2800 db = DB; 2619 2801 char buf[200]; 2620 sprintf(buf, "create table if not exists algo_hash_%d_%s ( hash integer, gameid integer, position integer);", boardsize, dbnameext.c_str());2802 sprintf(buf, "create table if not exists algo_hash_%d_%s ( hash integer, data blob );", boardsize, dbnameext.c_str()); 2621 2803 int rc = sqlite3_exec(db, buf, 0, 0, 0); 2622 2804 if (rc != SQLITE_OK) throw DBError(); … … 2624 2806 rc = sqlite3_exec(db, buf, 0, 0, 0); 2625 2807 if (rc != SQLITE_OK) throw DBError(); 2808 2809 updStmt = 0; 2810 insStmt = 0; 2811 selStmt = 0; 2626 2812 // printf("leave algo_hash::initialize_processing\n"); 2627 2813 } … … 2709 2895 2710 2896 void Algo_hash::finalize_process() { 2897 int rc; 2898 rc = sqlite3_finalize(insStmt); 2899 if (rc != SQLITE_OK) printf("error 14: %d\n", rc); // return rc; 2900 // else printf("ok 14\n"); 2901 rc = sqlite3_finalize(updStmt); 2902 if (rc != SQLITE_OK) printf("error 15: %d\n", rc); // return rc; 2903 // else printf("ok 15\n"); 2904 rc = sqlite3_finalize(selStmt); 2905 if (rc != SQLITE_OK) printf("error 13: %d\n", rc); // throw DBError(); 2906 insStmt = 0; 2907 updStmt = 0; 2908 selStmt = 0; 2711 2909 } 2712 2910 2713 2911 CompleteHashKey Algo_hash::compute_hashkey(PatternList& pl, int CS) { 2714 2912 return CompleteHashKey(); 2715 }2716 2717 int insert_result(void *rN, int argc, char **argv, char **azColName) throw (DBError) {2718 vector<HashhitCS* >* results = ((pair<vector<HashhitCS* >*, hashtype>*)rN)->first;2719 hashtype hashCode = ((pair<vector<HashhitCS* >*, hashtype>*)rN)->second;2720 2721 if (argc==3 && argv[0] && argv[1] && argv[2]) {2722 // printf("found %s, %lld", argv[2], atoi(argv[2]));2723 #if (defined(__BORLANDC__) || defined(_MSC_VER))2724 ((vector<HashhitCS* >*)results)->push_back(new HashhitCS(atoi(argv[0]), atoi(argv[1]), _atoi64(argv[2])!=hashCode));2725 #else2726 ((vector<HashhitCS* >*)results)->push_back(new HashhitCS(atoi(argv[0]), atoi(argv[1]), atoll(argv[2])!=hashCode));2727 #endif2728 } else throw DBError();2729 return 0;2730 2913 } 2731 2914 … … 2735 2918 // (this is necessary since the subpattern used for the hashing may not be 2736 2919 // located at the top left corner of the pattern) 2737 return HashQuery( "", 0, 0, 0, 0, 0, 0, 0);2920 return HashQuery(); 2738 2921 } 2739 2922 2740 2923 vector<int>* flip_list(int fl, int flip, int* pattern_ft, int* subpattern_ft) { 2924 // meaning of fl: 2925 // fl is the flip which maps the subpattern of the original search pattern to 2926 // the pattern which has hash code hashCode: hash(fl*subpattern) == hashCode. 2927 // 2928 // meaning of flip (this comes from the hash db): 2929 // Let (P, pos) be the pattern (and position) which has the hashCode we have searched for. 2930 // We assume that P is the unique pattern among all g(P) (g in the 2931 // symmetry group (modulo the stabilizer of P)) with this hashCode. 2932 // In the concerning game, since the game is in the list of results, one of the 2933 // g(P, pos) occurs, and specifically, g == flip^{-1}. 2934 // 2935 // so we find fl * i * subpattern == P (for all i in the stabilizer of subpattern), 2936 // and hence flip^{-1} * fl * i * subpattern == flip^{-1} P is the pattern which 2937 // occurs (probably) in the game, at position pos. 2938 // 2939 // in the candidates list, entries are of the form (pp, index) - this means that a 2940 // the pattern patternList.data[index] might occur at position pp. So for pp we use flip^{-1}*pos, 2941 // adjusted to take into account that we deal with a subpattern instead of the complete search pattern 2942 // (see Algo_hash::search). As index we use all those such that the corresponding flip has 2943 // the form flip^{-1} * fl * i (i in Stab(subpattern)/Stab(pattern)). 2944 2741 2945 vector<int>* result = new vector<int>; 2742 2946 bool used[8]; 2947 printf("pft "); for(int i=0; i<8; i++) printf("%d, ", pattern_ft[i]); printf("\n"); 2948 printf("sft "); 2949 for(int i=0; i<8; i++) 2950 printf("%d, ", subpattern_ft[i]); 2951 printf("\n"); 2743 2952 { for(int i=0; i<8; i++) used[i] = false; 2744 2953 } 2745 2954 { for(int i=0; i<8; i++) { 2746 if (subpattern_ft[i] || used[i]) continue; 2747 for(int j=1; j<8; j++) 2748 if (pattern_ft[j] == 0) used[Pattern::compose_flips(i,j)] = true; 2749 result->push_back(Pattern::compose_flips(Pattern::PatternInvFlip(fl), Pattern::compose_flips(flip, i))); 2955 if (subpattern_ft[i] || used[i]) 2956 continue; 2957 for(int j=1; j<8; j++) 2958 if (pattern_ft[j] == 0) used[Pattern::compose_flips(i,j)] = true; 2959 result->push_back(Pattern::compose_flips(Pattern::compose_flips(Pattern::PatternInvFlip(flip), Pattern::PatternInvFlip(fl)), i)); 2750 2960 } 2751 2961 } … … 2755 2965 int Algo_hash::search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db) { 2756 2966 // return value: -1 = failure; 0 = ok, but have to check w/ Algo_movelist 2757 bool cs = patternList.data[patternList.size()-1].colorSwitch; 2758 vector<HashhitCS* >* results = new vector<HashhitCS* >; 2967 HashCTREntry* results = new HashCTREntry; 2759 2968 2760 2969 HashQuery query = searchQuery(patternList); … … 2766 2975 if (gl.start_sorted() == 0) { 2767 2976 // query database 2768 pair<vector<HashhitCS* >*, hashtype> rN(results, query.hashCode0); 2769 sqlite3_exec(db, query.sql.c_str(), insert_result, &rN, 0); 2977 printf("sql query: %s\n", query.sql.c_str()); 2978 sqlite3_stmt* selStmt = 0; 2979 int rc = sqlite3_prepare(db, query.sql.c_str(), -1, &selStmt, 0); 2980 if (rc != SQLITE_OK || selStmt==0) return -1; 2981 while (sqlite3_step(selStmt) == SQLITE_ROW) { 2982 results->add((unsigned char*)sqlite3_column_blob(selStmt, 0), 2983 sqlite3_column_bytes(selStmt, 0), 2984 sqlite3_column_int64(selStmt, 1) != query.hashCode0); 2985 } 2986 if (rc != SQLITE_OK) printf("SQLITE errorA %d\n", rc); // FIXME 2987 rc = sqlite3_finalize(selStmt); 2988 if (rc != SQLITE_OK) printf("SQLITE errorB %d\n", rc); 2989 printf("%d results\n", results->data.size()); 2770 2990 2771 2991 // communicate results of query to database 2772 2992 // 2773 2993 // FIXME explain how we get from a hit for the sql query to a candidates entry! 2774 vector<HashhitCS* >::iterator resultIT = results-> begin();2775 while (resultIT != results-> end()) {2994 vector<HashhitCS* >::iterator resultIT = results->data.begin(); 2995 while (resultIT != results->data.end()) { 2776 2996 // printf("gid %d\n", (*resultIT)->gameid); 2777 2997 int index = (*resultIT)->gameid; … … 2779 2999 vector<Candidate* >* candidates = new vector<Candidate* >; 2780 3000 while ((*resultIT)->gameid == index) { 2781 int pos = (*resultIT)-> position % (1<<16);2782 int ori = (*resultIT)-> position / (1<<16);3001 int pos = (*resultIT)->get_pos(); 3002 int ori = (*resultIT)->get_ori(); 2783 3003 // printf("%d %d\n", pos, ori); 2784 3004 … … 2786 3006 int* subpattern_flipTable; 2787 3007 int fl; 2788 int offset; 3008 int offX = query.get_offX(); 3009 int offY = query.get_offY(); 3010 int subp_sizeX; 3011 int subp_sizeY; 2789 3012 if ((*resultIT)->cs) { 2790 3013 subpattern_flipTable = query.pl1->flipTable; 2791 3014 fl = query.flip1; 2792 offset = query.offset1; 3015 subp_sizeX = query.pl1->pattern.sizeX; 3016 subp_sizeY = query.pl1->pattern.sizeY; 2793 3017 } else { 2794 3018 subpattern_flipTable = query.pl0->flipTable; 2795 3019 fl = query.flip0; 2796 offset = query.offset0; 3020 subp_sizeX = query.pl0->pattern.sizeX; 3021 subp_sizeY = query.pl0->pattern.sizeY; 2797 3022 } 2798 3023 vector<int>* f_list = flip_list(fl, ori, pattern_flipTable, subpattern_flipTable); 2799 3024 for(vector<int>::iterator flip = f_list->begin(); flip != f_list->end(); flip++) { 2800 // position = pos - flip(p.offset) 2801 int pos_left = 0; 2802 int pos_top = 0; 2803 2804 candidates->push_back(new Candidate(pos_left, pos_top, *flip)); 3025 // *flip is such that (*flip) * subpattern should/could occur in the game at position ori^{-1}*pos 3026 // position of the candidate is hence = ori^{-1}*pos - p.offset 3027 int FLIP = *flip; 3028 int pos_left = pos%boardsize; // Pattern::flipsX(Pattern::PatternInvFlip(ori), (pos%boardsize), (pos/boardsize), boardsize-1, boardsize-1); 3029 pos_left -= min(Pattern::flipsX(FLIP, offX, offY, patternList.pattern.sizeX, patternList.pattern.sizeY), 3030 Pattern::flipsX(FLIP, offX + subp_sizeX, offY + subp_sizeY, 3031 patternList.pattern.sizeX, patternList.pattern.sizeY)); 3032 int pos_top = pos/boardsize -\ 3033 min(Pattern::flipsY(FLIP, offX, offY, patternList.pattern.sizeX, patternList.pattern.sizeY), 3034 Pattern::flipsY(FLIP, offX + subp_sizeX, offY + subp_sizeY, 3035 patternList.pattern.sizeX, patternList.pattern.sizeY)); 3036 int index; 3037 if (!(*resultIT)->cs) index = patternList.flipTable[*flip]; 3038 else index = patternList.flipTable[*flip + 8]; 3039 // printf("make cand %d, %d, %d\n", pos_left, pos_top, index); 3040 candidates->push_back(new Candidate(pos_left, pos_top, index)); 2805 3041 } 2806 3042 delete f_list; 2807 3043 resultIT++; 2808 if (resultIT == results-> end()) break;3044 if (resultIT == results->data.end()) break; 2809 3045 } 2810 3046 gl.makeIndexCandidate(index, candidates); 2811 3047 } 2812 for(vector<HashhitCS* >::iterator it = results->begin(); it != results->end(); it++) delete *it;2813 3048 delete results; 2814 3049 gl.end_sorted(); … … 2834 3069 2835 3070 CompleteHashKey Algo_hash_corner::compute_hashkey(PatternList& pl, int CS) { 2836 if (pl.data[0].sizeX < size || pl.data[0].sizeY < size || pl.data[0].left != pl.data[0].right || pl.data[0].top != pl.data[0].bottom || (pl.data[0].left != 0 && pl.data[0].left != boardsize-size) || (pl.data[0].top != 0 && pl.data[0].top != boardsize-size)) return CompleteHashKey(); 3071 // This method should receive the PatternList for a pattern of the correct size 3072 // (so a suitable subpattern has to be determined before) 3073 3074 // printf("Algo_hash_corner::compute_hashkey\n"); 3075 2837 3076 hashtype hk = NOT_HASHABLE; 2838 3077 int f = 0; 2839 int oX = 0;2840 int oY = 0;2841 3078 vector<hashtype> hCodes; 3079 // printf("before loop %d %d\n", pl.size(), CS); 2842 3080 for(int pCtr=0; pCtr<pl.size(); pCtr++) { 2843 3081 if (CS == pl.data[pCtr].colorSwitch) { 3082 // printf("loop %d\n", pCtr); 2844 3083 hashtype hashkey = 0; 2845 3084 int ns = 0; 2846 3085 2847 3086 Pattern *pattern = & pl.data[pCtr]; 2848 int offsetX = 0; 2849 int offsetY = 0; 2850 if (pattern->left > 0) offsetX = boardsize-size-pattern->left; // pattern located on east side of board 2851 if (pattern->top > 0) offsetY = boardsize-size-pattern->top; // ... south ... 3087 2852 3088 for(int i=0; i<size; i++) { 2853 3089 for(int j=0; j<size; j++) { 2854 char p = pattern->finalPos[i+offsetX + pattern->sizeX*(j+offsetY)]; 2855 if (p == 'x' || p == 'o' || p == '*') return CompleteHashKey(); 3090 char p = pattern->finalPos[i + pattern->sizeX*j]; 3091 if (p == 'x' || p == 'o' || p == '*') { 3092 printf("c_h 0a\n"); 3093 return CompleteHashKey(); 3094 } 2856 3095 else if (p == 'X') { 2857 hashkey += hashCodes[i+ offsetX+pattern->left + boardsize*(j+offsetY+pattern->top)];3096 hashkey += hashCodes[i+pattern->left + boardsize*(j+pattern->top)]; 2858 3097 ns++; 2859 3098 } else if (p == 'O') { 2860 hashkey -= hashCodes[i+ offsetX+pattern->left + boardsize*(j+offsetY+pattern->top)];3099 hashkey -= hashCodes[i+pattern->left + boardsize*(j+pattern->top)]; 2861 3100 ns++; 2862 3101 } 2863 3102 } 2864 3103 } 2865 if (ns < 3 || ns > maxNumStones) return CompleteHashKey(); // NOT_HASHABLE 3104 if (ns < 0 || ns > maxNumStones) { // FIXME: ns < 3! 3105 // printf("c_h 1\n"); 3106 return CompleteHashKey(); // NOT_HASHABLE 3107 } 2866 3108 2867 3109 // make sure all hash keys are unique 2868 3110 for(vector<hashtype>::iterator it = hCodes.begin(); it != hCodes.end(); it++) 2869 if (*it == hashkey) return CompleteHashKey(); // NOT_HASHABLE 3111 if (*it == hashkey) { 3112 // printf("c_h 2\n"); 3113 return CompleteHashKey(); // NOT_HASHABLE 3114 } 3115 // printf("push back %lld\n", hashkey); 2870 3116 hCodes.push_back(hashkey); 2871 3117 2872 3118 if (hk==NOT_HASHABLE || hashkey<hk) { 3119 // printf("found hk\n"); 2873 3120 hk = hashkey; 2874 3121 f = pCtr; 2875 oX = offsetX;2876 oY = offsetY;2877 3122 } 2878 3123 } 2879 3124 } 2880 return CompleteHashKey(hk, oX, oY,f);3125 return CompleteHashKey(hk, f); 2881 3126 } 2882 3127 2883 3128 HashQuery Algo_hash_corner::searchQuery(PatternList& patternList) { 2884 CompleteHashKey chk = compute_hashkey(patternList, 0); 2885 if (chk.hashCode == NOT_HASHABLE) return HashQuery("",0,0,0,0,0,0,0); 2886 int fl = patternList.data[chk.index].flip; 3129 printf("Enter Algo_hash_corner::search\n"); 3130 if (patternList.data[0].sizeX < size ||\ 3131 patternList.data[0].sizeY < size ||\ 3132 patternList.data[0].left != patternList.data[0].right ||\ 3133 patternList.data[0].top != patternList.data[0].bottom ||\ 3134 (patternList.data[0].left != 0 && patternList.data[0].left != boardsize-size) ||\ 3135 (patternList.data[0].top != 0 && patternList.data[0].top != boardsize-size)) { 3136 printf("c_h 0\n"); 3137 return HashQuery(); 3138 } 3139 3140 Pattern* pattern = &(patternList.data[0]); 3141 int offsetX = 0; 3142 int offsetY = 0; 3143 if (pattern->left > 0) offsetX = boardsize-size-pattern->left; // pattern located on east side of board 3144 if (pattern->top > 0) offsetY = boardsize-size-pattern->top; // ... south ... 3145 3146 Pattern subp = pattern->subpattern(offsetX, offsetY, size, size); 3147 PatternList sub_pl(subp, 0, 0); 3148 CompleteHashKey chk0 = compute_hashkey(sub_pl, 0); 3149 if (chk0.hashCode == NOT_HASHABLE) { 3150 printf("0 NH\n"); 3151 return HashQuery(); 3152 } 3153 int fl = patternList.data[chk0.index].flip; 2887 3154 2888 3155 char buf[100]; 2889 sprintf(buf, "select gameid,position,hash from algo_hash_%d_%s where hash = %lld",2890 boardsize, dbnameext.c_str() , chk.hashCode);3156 sprintf(buf, "select data,hash from algo_hash_%d_%s where hash ", 3157 boardsize, dbnameext.c_str()); 2891 3158 string sql = buf; 2892 Pattern* p0; // FIXME 2893 int off0 = 0; 2894 2895 hashtype hashCode2 = chk.hashCode; 3159 Pattern* p0 = new Pattern(sub_pl.data[0]); 3160 2896 3161 int fl2 = fl; 2897 3162 Pattern* p1 = 0; 2898 int off1 = 0;2899 3163 if (patternList.data[patternList.size()-1].colorSwitch) { 2900 CompleteHashKey hco = compute_hashkey(patternList, 1); 2901 hashCode2 = hco.hashCode; 3164 CompleteHashKey chk1 = compute_hashkey(sub_pl, 1); 2902 3165 // printf("HC2 %lld\n", hashCode2); 2903 if (chk.hashCode == NOT_HASHABLE) return HashQuery("",0,0,0,0,0,0,0); 2904 fl2 = patternList.data[hco.index].flip; 2905 2906 if (chk.hashCode != hashCode2) { 2907 sprintf(buf, " or hash = %lld", hashCode2); 3166 if (chk1.hashCode == NOT_HASHABLE) { 3167 printf("1 NH\n"); 3168 return HashQuery(); 3169 } 3170 fl2 = patternList.data[chk1.index].flip; 3171 3172 if (chk0.hashCode != chk1.hashCode) { 3173 sprintf(buf, "in ('%lld', '%lld')", chk0.hashCode, chk1.hashCode); 2908 3174 sql += buf; 2909 } 2910 } 2911 sql += " order by gameid"; 2912 return HashQuery(sql, p0, off0, fl, chk.hashCode, p1, off1, fl2); // FIXME: need to create subpatterns!, compute offsets 3175 p1 = new Pattern(sub_pl.data[sub_pl.size()/2]); 3176 } else { 3177 sprintf(buf, "= '%lld'", chk0.hashCode); 3178 sql += buf; 3179 } 3180 } else { 3181 sprintf(buf, "= '%lld'", chk0.hashCode); 3182 sql += buf; 3183 } 3184 return HashQuery(sql, p0, offsetX, offsetY, fl, chk0.hashCode, p1, fl2); 2913 3185 } 2914 3186 … … 2968 3240 2969 3241 void Algo_hash_center::initialize_process(sqlite3* DB) throw(DBError) { 2970 db = DB; 2971 char buf[200]; 2972 sprintf(buf, "create table if not exists algo_hash_%d_%s ( hash integer, gameid integer, position integer );", boardsize, dbnameext.c_str()); 2973 int rc = sqlite3_exec(db, buf, 0, 0, 0); 2974 if (rc != SQLITE_OK) throw DBError(); 2975 // create index in finalize_process in this case 2976 sprintf(buf, "drop index if exists hash_idx_%d_%s on algo_hash_%d_%s(hash);", boardsize, dbnameext.c_str(), boardsize, dbnameext.c_str()); 2977 rc = sqlite3_exec(db, buf, 0, 0, 0); 2978 if (rc != SQLITE_OK) throw DBError(); 2979 3242 Algo_hash::initialize_process(DB); 2980 3243 hi = new vector<HashInstance* >; 2981 3244 for(int i=0; i<boardsize-3; i++) // FIXME: boundaries 2982 3245 for(int j=0; j<boardsize-3; j++) 2983 3246 hi->push_back(new HashInstanceCTR(i, j, 4, 4, boardsize)); 2984 }2985 2986 void Algo_hash_center::finalize_process() {2987 char buf[200];2988 sprintf(buf, "create index if not exists hash_idx_%d_%s on algo_hash_%d_%s(hash);", boardsize, dbnameext.c_str(), boardsize, dbnameext.c_str());2989 int rc = sqlite3_exec(db, buf, 0, 0, 0);2990 if (rc != SQLITE_OK) throw DBError();2991 3247 } 2992 3248 … … 3005 3261 currentHashCode[f] |= 1 << p; // set to 01 = black 3006 3262 else if (c == 'W') 3007 currentHashCode[f] |= 1 << p+1; // set to 10 = white3263 currentHashCode[f] |= 1 << (p+1); // set to 10 = white 3008 3264 else if (c != '.') return NOT_HASHABLE; 3009 3265 } … … 3042 3298 3043 3299 HashQuery Algo_hash_center::searchQuery(PatternList& patternList) { 3044 return HashQuery( "",0,0,0,0,0,0,0);3300 return HashQuery(); 3045 3301 } 3046 3302 … … 3202 3458 int p = 2*(4*x1+y1); 3203 3459 currentHashCode[i] ^= ((currentHashCode[i] >> p)%4) << p; // set to 00 3204 currentHashCode[i] |= 1 << p+1; // set to 10 = white3460 currentHashCode[i] |= 1 << (p+1); // set to 10 = white 3205 3461 } 3206 3462 } … … 4165 4421 4166 4422 void GameList::makeCurrentCandidate(vector<Candidate* > * candidates) { 4423 printf("GameList::makeCurrentCandidate\n"); 4167 4424 GameListEntry* gle = (*all)[(*oldList)[current].second]; 4168 4425 if (gle->candidates) delete gle->candidates; 4169 4426 gle->candidates = candidates; 4427 for(vector<Candidate* >::iterator it = candidates->begin(); it != candidates->end(); it++) { 4428 printf("x: %d, y: %d, flip: %d\n", (*it)->x, (*it)->y, (*it)->orientation); 4429 } 4170 4430 currentList->push_back((*oldList)[current]); 4171 4431 } … … 4568 4828 sizeX = pattern.sizeX; // need this in lookupLabel 4569 4829 PatternList pl(pattern, searchOptions->fixedColor, searchOptions->nextMove); 4830 printf("created pl, size: %d\n", pl.size()); 4831 // for(int i=0; i< pl.size(); i++) printf("%s\n", pl.data[i].printPattern().c_str()); 4570 4832 4571 4833 vector<int>::iterator it = boardsizes.begin(); … … 4611 4873 if (hash_result == 0) { 4612 4874 if (searchOptions->algos & ALGO_MOVELIST && algo_ps[algo_movelist+20*bs_index]) 4875 printf("movelist 0\n"); 4613 4876 algo_ps[algo_movelist+20*bs_index]->search(pl, *this, *searchOptions); 4614 4877 } … … 4618 4881 if (searchOptions->algos & ALGO_FINALPOS && algo_ps[algo_finalpos+20*bs_index]) 4619 4882 algo_ps[algo_finalpos+20*bs_index]->search(pl, *this, *searchOptions); 4883 printf("movelist 1\n"); 4620 4884 if (searchOptions->algos & ALGO_MOVELIST && algo_ps[algo_movelist+20*bs_index]) 4621 4885 algo_ps[algo_movelist+20*bs_index]->search(pl, *this, *searchOptions); … … 4811 5075 int rc = sqlite3_exec(algo_db2, "commit", 0, 0, 0); 4812 5076 if (rc) { 4813 sqlite3_close( db);4814 db= 0;5077 sqlite3_close(algo_db2); 5078 algo_db2 = 0; 4815 5079 throw DBError(); 4816 5080 } 4817 5081 rc = sqlite3_exec(algo_db2, "begin transaction", 0, 0, 0); 4818 5082 if (rc) { 4819 sqlite3_close( db);4820 db= 0;5083 sqlite3_close(algo_db2); 5084 algo_db2 = 0; 4821 5085 throw DBError(); 4822 5086 } 06/libkombilo-branches/hash_center/search.h
r240 r241 28 28 #include <utility> 29 29 #include <stack> 30 <
