Changeset 239

Show
Ignore:
Timestamp:
03/09/07 16:38:11 (1 year ago)
Author:
ug
Message:

Handling of duplicates within GameList, also during process.
Better access to processing results.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • 06/libkombilo/Makefile

    r210 r239  
    22        g++ -o cpptest -lsqlite3 -lboost_filesystem cpptest.o search.o sgfparser.o abstractboard.o 
    33 
    4 cpptest.o: cpptest.cpp 
     4cpptest.o: cpptest.cpp search.h abstractboard.h sgfparser.h 
    55        g++ -c cpptest.cpp 
    66 
    7 search.o: search.cpp 
     7search.o: search.cpp search.h abstractboard.h sgfparser.h 
    88        g++ -c search.cpp 
    99 
    10 sgfparser.o: sgfparser.cpp 
     10sgfparser.o: sgfparser.cpp sgfparser.h 
    1111        g++ -c sgfparser.cpp 
    1212 
    13 abstractboard.o: abstractboard.cpp 
     13abstractboard.o: abstractboard.cpp abstractboard.h 
    1414        g++ -c abstractboard.cpp 
    1515 
  • 06/libkombilo/abstractboard.cpp

    r225 r239  
    8484  if (DEBUG_ABSTRACTBOARD) printf("AB::abstractBoard(int) 0\n"); 
    8585  boardsize = bs; 
    86   if (boardsize < 3) throw BoardError(); 
     86  if (boardsize < 3) throw BoardError(); // FIXME 
    8787  status = new char[boardsize*boardsize+1]; 
    8888  for (int i = 0; i < boardsize*boardsize; i++) 
  • 06/libkombilo/cpptest.cpp

    r230 r239  
    2929    gl.start_processing(); 
    3030    directory_iterator end_itr; 
    31     string path = "/home/ug/go/kombilo/06/libkombilo"; 
     31    // string path = "/home/ug/go/kombilo/06/libkombilo"; 
    3232    // string path = "/home/ug/go/gtl/reviews"; 
    33     // string path = "/home/ug/go/gogod06/2000"; 
     33    string path = "/home/ug/go/gogod06/1998"; 
     34    int counter = 0; 
    3435    for(directory_iterator it(path); it != end_itr; ++it) { 
    3536      string n = it->string(); 
     
    4647        } 
    4748        infile.close(); 
    48         gl.process(sgf.c_str(), path.c_str(), n.c_str());    
     49        int flags = CHECK_FOR_DUPLICATES; // |OMIT_DUPLICATES; 
     50        if (gl.process(sgf.c_str(), path.c_str(), n.c_str(), "", flags)) 
     51          if (gl.process_results() & IS_DUPLICATE) printf("is duplicate: %d\n", counter); 
     52        counter++; 
    4953      } 
    5054    } 
    5155    gl.finalize_processing(); 
    52     printf("Processed %d games.\n", gl.size()); 
     56    printf("Now %d games in db.\n", gl.size()); 
    5357  } 
    5458  printf("%d games.\n", gl.size()); 
     
    9094   
    9195  // -------------------- do pattern search -------------------------------------- 
    92   gl.search(p, &so); 
     96  // gl.search(p, &so); 
    9397 
    9498  // ------------------- print some information about current list of games ------------ 
    95   printf("num games: %d, num hits: %d\n", gl.size(), gl.numHits()); 
     99  // printf("num games: %d, num hits: %d\n", gl.size(), gl.numHits()); 
    96100  // vector<string> res = gl.currentEntriesAsStrings(); 
    97101  // for(vector<string>::iterator it = res.begin(); it != res.end(); it++) 
     
    100104 
    101105  // ------------------- print some statistics ------------------------------------------ 
    102   printf("Search pattern:\n"); 
    103   printf("%s\n", p.printPattern().c_str()); 
    104   printf("Continuations:\n"); 
    105   for(int y=0; y<p.sizeY; y++) { 
    106     for(int x=0; x<p.sizeX; x++) { 
    107       printf("%c", gl.lookupLabel(x,y)); 
     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); 
     118 
     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  // } 
     130 
     131  // ------------------- check for duplicates --------------------------------- 
     132  gl.reset(); 
     133  int nd = gl.find_duplicates(19); 
     134  printf("duplicates:\n"); 
     135  for(int i=0; i<nd; i++) { 
     136    // 1st method: retrieve_duplicates_VI 
     137    // vector<int> dupl_vector = gl.retrieve_duplicates_VI(i); 
     138    // for(vector<int>::iterator it = dupl_vector.begin(); it != dupl_vector.end(); it++) { 
     139    //   printf("%s%s\n", gl.currentEntryAsString(*it).c_str(), gl.getSignature(*it).c_str()); 
     140    // } 
     141     
     142    // 2nd method: retrieve_duplicates_PI 
     143    int * dupl_vector = gl.retrieve_duplicates_PI(i); 
     144    int j = 0; 
     145    while(dupl_vector[j] != -1) { 
     146      printf("%s%s\n", gl.currentEntryAsString(dupl_vector[j]).c_str(), gl.getSignature(dupl_vector[j]).c_str()); 
     147      j++; 
    108148    } 
    109     printf("\n"); 
    110   } 
    111   printf("\n"); 
    112   printf("Statistics:\n");  
    113   printf("num hits: %d, num switched: %d, B wins: %d, W wins: %d\n", gl.num_hits, gl.num_switched, gl.Bwins, gl.Wwins); 
     149    delete [] dupl_vector; 
    114150 
    115   printf("Continuation | Black      ( B wins / W wins ) | White      (B wins / W wins) |\n"); 
    116   for(int y=0; y<p.sizeY; y++) { 
    117     for(int x=0; x<p.sizeX; x++) { 
    118       if (gl.lookupLabel(x,y) != '.') { 
    119         Continuation cont = gl.lookupContinuation(x,y); 
    120         printf("      %c      |   %3d[%3d] (    %3d /    %3d ) |   %3d[%3d] (   %3d /    %3d) | %1.1f /  %1.1f \n", 
    121             gl.lookupLabel(x,y), cont.B, cont.tB, cont.wB, cont.lB, cont.W, cont.tW, cont.wW, cont.lW,  
    122             cont.wW*100.0/cont.W, cont.wB*100.0/cont.B); 
    123       } 
    124     } 
     151    printf("--------------------------------------------------- \n"); 
    125152  } 
    126153 
  • 06/libkombilo/libkombilo.i

    r191 r239  
    55namespace std { 
    66  %template(vectors) vector<string>; 
     7  %template(vectori) vector<int>; 
    78}; 
    89 
  • 06/libkombilo/process.py

    r219 r239  
    3131    for filename in filenames: 
    3232        # print filename 
    33         counter += 1 
    3433        try: 
    3534            file = open(filename) 
     
    4140 
    4241        path, fn = os.path.split(filename) 
    43         gl.process(sgf, path, fn) 
     42        if gl.process(sgf, path, fn, '', CHECK_FOR_DUPLICATES_STRICT): 
     43            if gl.process_results() & IS_DUPLICATE:  
     44                print 'duplicate', counter 
     45        else: print 'SGF error' 
     46        counter += 1 
     47         
    4448    gl.finalize_processing() 
    4549    print 'Processed %d games in %.2f seconds' % (counter, time.time()-starttime) 
  • 06/libkombilo/search.cpp

    r230 r239  
    858858void Algorithm::branchpoint_process() {} 
    859859void Algorithm::endOfVariation_process() {} 
    860 void Algorithm::endgame_process() {} 
     860void Algorithm::endgame_process(bool commit) {} 
    861861void Algorithm::finalize_process() {} 
    862862int Algorithm::readDB(sqlite3* DB) { return 0; } 
     
    877877  sprintf(sql, "create table if not exists algo_signature_%d ( id integer primary key, signature varchar(12) );", boardsize); 
    878878  int rc = sqlite3_exec(db, sql, 0, 0, 0); 
     879  if (rc != SQLITE_OK) throw DBError(); 
     880  sprintf(sql, "create index if not exists sig_idx on algo_signature_%d(signature);", boardsize); 
     881  rc = sqlite3_exec(db, sql, 0, 0, 0); 
    879882  if (rc != SQLITE_OK) throw DBError(); 
    880883} 
     
    972975} 
    973976 
    974 void Algo_signature::endgame_process() throw(DBError) { 
    975   char* min_signature = symmetrize(signature, boardsize); 
     977void Algo_signature::endgame_process(bool commit) throw(DBError) { 
     978  if (commit) { 
     979    char* min_signature = symmetrize(signature, boardsize); 
     980    char sql[100]; 
     981    sprintf(sql, "insert into algo_signature_%d (id, signature) values (?,?);", boardsize); 
     982    if (dbinsert1blob(db, sql, gid, min_signature, 12)) throw DBError(); 
     983    // for(int i=0; i<12; i++) printf("%c", min_signature[i]); printf("\n"); 
     984    delete [] min_signature; 
     985  } 
    976986  delete [] signature; 
     987} 
     988 
     989void Algo_signature::finalize_process() { 
     990} 
     991 
     992char* Algo_signature::get_current_signature() { 
     993  return symmetrize(signature, boardsize); 
     994} 
     995 
     996vector<int> Algo_signature::search_signature(char* sig) { 
     997  // to be used during processing! (because we need the db) 
    977998  char sql[100]; 
    978   sprintf(sql, "insert into algo_signature_%d (id, signature) values (?,?);", boardsize); 
    979   if (dbinsert1blob(db, sql, gid, min_signature, 12)) throw DBError(); 
    980   // for(int i=0; i<12; i++) printf("%c", min_signature[i]); printf("\n"); 
    981   delete [] min_signature; 
    982 
    983  
    984 void Algo_signature::finalize_process() { 
    985 
    986  
     999  sprintf(sql, "select id from algo_signature_%d where signature=? order by id", boardsize); 
     1000  sqlite3_stmt *ppStmt=0; 
     1001  vector<int> result; 
     1002  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
     1003  if (rc != SQLITE_OK || ppStmt==0) throw DBError(); 
     1004  rc = sqlite3_bind_blob(ppStmt, 1, sig, 12, SQLITE_TRANSIENT); 
     1005  if (rc != SQLITE_OK || ppStmt==0) throw DBError(); 
     1006  do { 
     1007    rc = sqlite3_step(ppStmt); 
     1008    if (rc != SQLITE_DONE && rc != SQLITE_ROW) throw DBError(); 
     1009    if (rc == SQLITE_ROW) { 
     1010      result.push_back(sqlite3_column_int(ppStmt, 0)); 
     1011    } 
     1012  } while (rc == SQLITE_ROW); 
     1013  rc = sqlite3_finalize(ppStmt); 
     1014  if (rc != SQLITE_OK) throw DBError(); 
     1015  return result; 
     1016
    9871017 
    9881018Algo_finalpos::Algo_finalpos(int bsize) : Algorithm(bsize) { 
     
    10481078} 
    10491079 
    1050 void Algo_finalpos::endgame_process() throw(DBError) { 
    1051   char sql[100]; 
    1052   sprintf(sql, "insert into algo_finalpos_%d (id, data) values (?,?);", boardsize); 
    1053   if (dbinsert1blob(db, sql, gid, fp, 100)) throw DBError(); 
     1080void Algo_finalpos::endgame_process(bool commit) throw(DBError) { 
     1081  if (commit) { 
     1082    char sql[100]; 
     1083    sprintf(sql, "insert into algo_finalpos_%d (id, data) values (?,?);", boardsize); 
     1084    if (dbinsert1blob(db, sql, gid, fp, 100)) throw DBError(); 
     1085  } 
    10541086  delete [] fp; 
    10551087} 
     
    12261258} 
    12271259 
     1260bool Algo_finalpos::equal(unsigned int i1, unsigned int i2) {  
     1261  // not to be used during processing 
     1262  // i1, i2 correspond to game id's 
     1263  sqlite3_stmt *ppStmt=0; 
     1264  char sql[100]; 
     1265  sprintf(sql, "select data from algo_finalpos_%d where id = %d or id = %d", boardsize, i1, i2); 
     1266  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
     1267  if (rc != SQLITE_OK || ppStmt==0) return false; // FIXME: catch certain errors, (and/or throw DBError?) 
     1268  if (sqlite3_step(ppStmt) == SQLITE_ROW) { 
     1269    char* dd1 = (char*)sqlite3_column_blob(ppStmt, 0); 
     1270    char* d1 = new char[100]; 
     1271    for(int i=0; i<100; i++) d1[i] = dd1[i]; // FIXME: is this necessary? 
     1272    if (sqlite3_step(ppStmt) == SQLITE_ROW) { 
     1273      char* d2 = (char*)sqlite3_column_blob(ppStmt, 0); 
     1274      for(int i=0; i<100; i++)  
     1275        if (d1[i] != d2[i]) { 
     1276          delete [] d1; 
     1277          sqlite3_finalize(ppStmt); 
     1278          return false; 
     1279        } 
     1280      delete [] d1; 
     1281      sqlite3_finalize(ppStmt); 
     1282      return true; 
     1283    } 
     1284    delete [] d1; 
     1285  } 
     1286  sqlite3_finalize(ppStmt); 
     1287  return false; 
     1288} 
     1289 
     1290bool Algo_finalpos::equals_current(unsigned int id1) {  
     1291  // to be used only during processing 
     1292  // id1 here corresponds to a game id 
     1293  bool result = true; 
     1294  sqlite3_stmt *ppStmt=0; 
     1295  char sql[100]; 
     1296  sprintf(sql, "select data from algo_finalpos_%d where id = %d", boardsize, id1); 
     1297  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
     1298  if (rc != SQLITE_OK || ppStmt==0) return false; // FIXME: catch certain errors, (and/or throw DBError?) 
     1299  if (sqlite3_step(ppStmt) == SQLITE_ROW) { 
     1300    char* d = (char*)sqlite3_column_blob(ppStmt, 0); 
     1301    for(int i=0; i<100; i++)  
     1302      if (d[i] != fp[i]) { 
     1303        result = false; 
     1304        break; 
     1305      } 
     1306  } else result = false; 
     1307  sqlite3_finalize(ppStmt); 
     1308  return result; 
     1309} 
     1310 
    12281311 
    12291312Algo_movelist::Algo_movelist(int bsize) : Algorithm(bsize) { 
     
    13351418} 
    13361419 
    1337 void Algo_movelist::endgame_process() throw(DBError) { 
    1338   char* ml = new char[movelist.size()]; 
    1339   int mlIndex = 0; 
    1340   for(vector<char>::iterator it = movelist.begin(); it != movelist.end(); it++) { 
    1341     ml[mlIndex++] = *it; 
    1342   } 
    1343   char sql[100]; 
    1344   sprintf(sql, "insert into algo_movelist_%d (id, movelist, fpC) values (?, ?, ?);", boardsize); 
    1345   if (dbinsert2blobs(db, sql, gid, ml, mlIndex, fpC, 50)) throw DBError(); 
    1346   delete [] ml; 
     1420void Algo_movelist::endgame_process(bool commit) throw(DBError) { 
     1421  if (commit) { 
     1422    char* ml = new char[movelist.size()]; 
     1423    int mlIndex = 0; 
     1424    for(vector<char>::iterator it = movelist.begin(); it != movelist.end(); it++) { 
     1425      ml[mlIndex++] = *it; 
     1426    } 
     1427    char sql[100]; 
     1428    sprintf(sql, "insert into algo_movelist_%d (id, movelist, fpC) values (?, ?, ?);", boardsize); 
     1429    if (dbinsert2blobs(db, sql, gid, ml, mlIndex, fpC, 50)) throw DBError(); 
     1430    delete [] ml; 
     1431  } 
    13471432  delete [] fpC; 
    13481433} 
     
    20562141#endif 
    20572142 
     2143HashFEntry::HashFEntry(hashtype HASHCODE, char* BUF, int LENGTH) { 
     2144  hashCode = HASHCODE; 
     2145  buf = BUF; 
     2146  length = LENGTH; 
     2147} 
     2148 
     2149HashFEntry::HashFEntry(const HashFEntry& hfe) { 
     2150  hashCode = hfe.hashCode; 
     2151  length = hfe.length; 
     2152  buf = new char[length]; 
     2153  for(int i=0; i<length; i++) buf[i] = hfe.buf[i]; 
     2154} 
     2155 
     2156HashFEntry::~HashFEntry() { 
     2157  if (buf) { 
     2158    delete [] buf; 
     2159    buf = 0; 
     2160  } 
     2161} 
     2162 
    20582163HashhitF::HashhitF(int GAMEID, char ORIENTATION, char* blob) { 
    20592164  gameid = GAMEID; 
     
    21352240    buf[6+2*i] = mn.data[i]%256; 
    21362241  } 
     2242  hash_vector.push_back(HashFEntry(hashCode, buf, 5+2*mn.length)); 
     2243  return 0; 
     2244} 
     2245 
     2246int Algo_hash_full::insert_all_hashes() { 
    21372247  char sql[100]; 
    21382248  sprintf(sql, "insert into algo_hash_full_%d (hash, gameid, hit) values (?,?,?);", boardsize); 
     
    21402250  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
    21412251  if (rc != SQLITE_OK || ppStmt==0) return rc; 
    2142   rc = sqlite3_bind_int64(ppStmt, 1, hashCode); 
    2143   if (rc != SQLITE_OK) return rc; 
    2144   rc = sqlite3_bind_int(ppStmt, 2, gid); 
    2145   if (rc != SQLITE_OK) return rc; 
    2146   rc = sqlite3_bind_blob(ppStmt, 3, buf, 5+2*mn.length, SQLITE_TRANSIENT);  
    2147   if (rc != SQLITE_OK) return rc; 
    2148   rc = sqlite3_step(ppStmt); 
    2149   if (rc != SQLITE_DONE) return rc; 
     2252  for(vector<HashFEntry>::iterator it = hash_vector.begin(); it != hash_vector.end(); it++) { 
     2253    rc = sqlite3_bind_int64(ppStmt, 1, it->hashCode); 
     2254    if (rc != SQLITE_OK) return rc; 
     2255    rc = sqlite3_bind_int(ppStmt, 2, gid); 
     2256    if (rc != SQLITE_OK) return rc; 
     2257    rc = sqlite3_bind_blob(ppStmt, 3, it->buf, it->length, SQLITE_TRANSIENT);  
     2258    if (rc != SQLITE_OK) return rc; 
     2259    rc = sqlite3_step(ppStmt); 
     2260    if (rc != SQLITE_DONE) return rc; 
     2261    rc = sqlite3_reset(ppStmt); 
     2262    if (rc != SQLITE_OK) return rc; 
     2263  } 
    21502264  rc = sqlite3_finalize(ppStmt); 
    21512265  if (rc != SQLITE_OK) return rc; 
    2152   delete [] buf
     2266  hash_vector.clear()
    21532267  return 0; // success 
    21542268} 
     
    22642378} 
    22652379 
    2266 void Algo_hash_full::endgame_process() throw(DBError) { 
     2380void Algo_hash_full::endgame_process(bool commit) throw(DBError) { 
    22672381  for(vector<pair<hashtype, ExtendedMoveNumber>* >::iterator it = lfc->begin(); it != lfc->end(); it++) { 
    22682382    Move* continuation = 0; 
     
    22712385    delete *it; 
    22722386  } 
     2387  if (commit) { 
     2388    int rc = insert_all_hashes(); 
     2389    if (rc) printf("ouch %d\n",rc); 
     2390  } else hash_vector.clear(); 
    22732391  delete lfc; 
    22742392  delete moveNumber; 
     
    24202538 
    24212539int Algo_hash::insert_hash(hashtype hashCode, int pos) { 
    2422   // printf("insert %lld\n", hashCode); 
     2540  hash_vector.push_back(make_pair(hashCode, pos)); 
     2541  return 0; 
     2542
     2543 
     2544int Algo_hash::insert_all_hashes() { 
     2545  // printf("insert all hashes %d\n", hash_vector.size()); 
    24232546  char sql[200]; 
    24242547  sprintf(sql, "insert into algo_hash_%d_%s (hash, gameid, position) values (?,?,?);", boardsize, dbnameext.c_str()); 
     
    24262549  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
    24272550  if (rc != SQLITE_OK || ppStmt==0) return rc; 
    2428   rc = sqlite3_bind_int64(ppStmt, 1, hashCode); 
    2429   if (rc != SQLITE_OK) return rc; 
    24302551  rc = sqlite3_bind_int(ppStmt, 2, gid); 
    24312552  if (rc != SQLITE_OK) return rc; 
    2432   rc = sqlite3_bind_int(ppStmt, 3, pos); 
    2433   if (rc != SQLITE_OK) return rc; 
    2434   rc = sqlite3_step(ppStmt); 
    2435   if (rc != SQLITE_DONE) return rc; 
     2553  for(vector<pair<hashtype, int> >::iterator it = hash_vector.begin(); it != hash_vector.end(); it++) { 
     2554    // printf("insert %d %d\n", it->first, it->second); 
     2555    rc = sqlite3_bind_int64(ppStmt, 1, it->first); 
     2556    if (rc != SQLITE_OK) return rc; 
     2557    rc = sqlite3_bind_int(ppStmt, 3, it->second); 
     2558    if (rc != SQLITE_OK) return rc; 
     2559    rc = sqlite3_step(ppStmt); 
     2560    if (rc != SQLITE_DONE) return rc; 
     2561    rc = sqlite3_reset(ppStmt); 
     2562    if (rc != SQLITE_OK) return rc; 
     2563  } 
    24362564  rc = sqlite3_finalize(ppStmt); 
    24372565  if (rc != SQLITE_OK) return rc; 
     
    24812609      it->changed = false; 
    24822610      pair<hashtype,int> phi = it->cHC(); 
    2483       if (insert_hash(phi.first, phi.second) != 0) throw DBError(); 
     2611      insert_hash(phi.first, phi.second); 
     2612      // printf("insert hash CORNER %d %d\n", phi.first, phi.second); 
    24842613    } 
    24852614  } 
     
    25222651} 
    25232652 
    2524 void Algo_hash::endgame_process() { 
     2653void Algo_hash::endgame_process(bool commit) { 
    25252654  for(vector<HashInstance>::iterator it = hi->begin(); it != hi->end(); it++) 
    25262655    it->finalize(); 
     2656  if (commit) { 
     2657    int rc = insert_all_hashes(); 
     2658    if (rc) printf("ouch %d\n",rc); 
     2659    hash_vector.clear(); 
     2660  } else hash_vector.clear(); 
    25272661} 
    25282662  
     
    26782812        } 
    26792813      } 
    2680       if (ns > maxNumStones) return make_pair(NOT_HASHABLE,0); 
     2814      if (ns < 3 || ns > maxNumStones) return make_pair(NOT_HASHABLE,0); 
    26812815 
    26822816      // make sure all hash keys are unique 
     
    33573491  if (rootNodeTags.find("RE") == string::npos) rootNodeTags += ",RE"; 
    33583492  if (rootNodeTags.find("DT") == string::npos) rootNodeTags += ",DT"; 
     3493 
     3494  algos |= ALGO_FINALPOS | ALGO_MOVELIST; // these are mandatory at the moment 
    33593495} 
    33603496 
     
    34413577 
    34423578GameList::GameList(char* DBNAME, string ORDERBY, string FORMAT, ProcessOptions* p_options, int cache) throw(DBError) { 
     3579  duplicates = 0; 
    34433580  labels = 0; 
    34443581  continuations = 0; 
     
    36713808  if (labels) delete [] labels; 
    36723809  if (continuations) delete [] continuations; 
     3810  if (duplicates) delete duplicates; 
    36733811  delete [] dbname; 
    36743812  if (all) { 
     
    37803918 
    37813919void GameList::makeIndexHit(int index, vector<Hit* > * hits) { 
    3782   int start = current; 
    3783   int end = oldList->size(); 
    3784   int m = start; 
    3785   while (start < end) { 
    3786     m = (end+start)/2; 
    3787     if (index == (*oldList)[m].first) { 
    3788       currentList->push_back((*oldList)[m]); 
    3789       if (hits) { 
    3790         if ((*all)[(*oldList)[m].second]->hits) delete (*all)[(*oldList)[m].second]->hits; 
    3791         (*all)[(*oldList)[m].second]->hits = hits; 
    3792       } 
    3793       break; 
    3794     } else { 
    3795       if (index < (*oldList)[m].first) end = m; 
    3796       else start = m+1; 
    3797     } 
    3798   } 
    3799   current = m; 
     3920  int m = get_current_index(index, &current); 
     3921  if (m != -1) { 
     3922    currentList->push_back((*oldList)[m]); 
     3923    if (hits) { 
     3924      if ((*all)[(*oldList)[m].second]->hits) delete (*all)[(*oldList)[m].second]->hits; 
     3925      (*all)[(*oldList)[m].second]->hits = hits; 
     3926    } 
     3927  } 
    38003928} 
    38013929 
    38023930void GameList::makeIndexCandidate(int index, vector<Candidate* > * candidates) { 
    3803   int start = current; 
    3804   int end = oldList->size(); 
    3805   int m = start; 
    3806   while (start < end) { 
    3807     m = (end+start)/2; 
    3808     if (index == (*oldList)[m].first) { 
    3809       currentList->push_back((*oldList)[m]); 
    3810       if (candidates) { 
    3811         if ((*all)[(*oldList)[m].second]->candidates) delete (*all)[(*oldList)[m].second]->candidates; 
    3812         (*all)[(*oldList)[m].second]->candidates = candidates; 
    3813       } 
    3814       break; 
    3815     } else { 
    3816       if (index < (*oldList)[m].first) end = m; 
    3817       else start = m+1; 
    3818     } 
    3819   } 
    3820   current = m; 
     3931  int m = get_current_index(index, &current); 
     3932  if (m != -1) { 
     3933    currentList->push_back((*oldList)[m]); 
     3934    if (candidates) { 
     3935      if ((*all)[(*oldList)[m].second]->candidates) delete (*all)[(*oldList)[m].second]->candidates; 
     3936      (*all)[(*oldList)[m].second]->candidates = candidates; 
     3937    } 
     3938  } 
    38213939} 
    38223940 
     
    38954013  if (rc != SQLITE_OK) throw DBError(); 
    38964014  return result; 
     4015} 
     4016 
     4017void GameList::insert_duplicate(int i1, int i2, vector<vector<int> >* dupl) { 
     4018  int ii1 = get_current_index_CL(i1); 
     4019  int ii2 = get_current_index_CL(i2); 
     4020  // printf("insert_duplicate %d, %d\n", ii1, ii2); 
     4021  if (ii1 == -1 || ii2 == -1) return; 
     4022  bool inserted = false; 
     4023  for(vector<vector<int> >::iterator it = dupl->begin(); it != dupl->end(); it++) { 
     4024    vector<int>::iterator i = it->begin(); 
     4025    while(i != it->end() && *i != ii1 && *i != ii2) i++; 
     4026    if (i == it->end()) continue; 
     4027    int insert = ii1; 
     4028    if (*i == ii1) insert = ii2; 
     4029    while (i != it->end() && *i != insert) i++; 
     4030    if (i == it->end()) it->push_back(insert); 
     4031    sort(it->begin(), it->end()); 
     4032    inserted = true; 
     4033    break; 
     4034  } 
     4035  if (!inserted) { 
     4036    vector<int> new_list; 
     4037    if (ii1 < ii2) { 
     4038      new_list.push_back(ii1); 
     4039      new_list.push_back(ii2); 
     4040    } else { 
     4041      new_list.push_back(ii2); 
     4042      new_list.push_back(ii1); 
     4043    } 
     4044    dupl->push_back(new_list); 
     4045  } 
     4046} 
     4047 
     4048int GameList::find_duplicates(int bs, bool strict) throw(DBError) { 
     4049  int bs_index = 0; 
     4050  if (duplicates) delete duplicates; 
     4051  duplicates = new vector<vector<int> >; 
     4052  if (strict) { 
     4053    vector<int>::iterator it = boardsizes.begin(); 
     4054    while (it != boardsizes.end() && *it != bs) { 
     4055      bs_index++; 
     4056      it++; 
     4057    } 
     4058    if (it == boardsizes.end()) { 
     4059      return 0; 
     4060    } 
     4061  } 
     4062  sort(currentList->begin(), currentList->end()); 
     4063  sqlite3_stmt *ppStmt=0; 
     4064  char sql[200]; 
     4065  sprintf(sql, "select as1.id,as2.id from algo_signature_%d as1 join algo_signature_%d as2 on as1.signature = as2.signature where as1.id < as2.id;", bs, bs); 
     4066  int rc = sqlite3_prepare(db, sql, -1, &ppStmt, 0); 
     4067  if (rc != SQLITE_OK || ppStmt==0) throw DBError(); 
     4068  do { 
     4069    rc = sqlite3_step(ppStmt); 
     4070    if (rc != SQLITE_DONE && rc != SQLITE_ROW) throw DBError(); 
     4071    if (rc == SQLITE_ROW) { 
     4072      if (!strict || ((Algo_finalpos*)algo_ps[20*bs_index+algo_finalpos])->equal(sqlite3_column_int(ppStmt, 0), sqlite3_column_int(ppStmt, 1))) 
     4073        insert_duplicate(sqlite3_column_int(ppStmt, 0), sqlite3_column_int(ppStmt, 1), duplicates); 
     4074    } 
     4075  } while (rc == SQLITE_ROW); 
     4076  rc = sqlite3_finalize(ppStmt); 
     4077  if (rc != SQLITE_OK) throw DBError(); 
     4078  sort(currentList->begin(), currentList->end(), sndcomp); 
     4079  return duplicates->size(); 
     4080} 
     4081 
     4082vector<int> GameList::retrieve_duplicates_VI(unsigned int i) { 
     4083  if (i>=duplicates->size()) return vector<int>(); 
     4084  return (*duplicates)[i]; 
     4085} 
     4086 
     4087int* GameList::retrieve_duplicates_PI(unsigned int i) { 
     4088  if (i>=duplicates->size()) return 0; 
     4089  int* result = new int[(*duplicates)[i].size()+1]; 
     4090  int j = 0; 
     4091  for(vector<int>::iterator it = (*duplicates)[i].begin(); it != (*duplicates)[i].end(); it++) 
     4092    result[j++] = *it; 
     4093  result[(*duplicates)[i].size()] = -1; 
     4094  return result; 
     4095} 
     4096 
     4097 
     4098int GameList::get_current_index(int id, int* start) { 
     4099  // use this in between start_sorted() and end_sorted() only! 
     4100  int end = oldList->size(); 
     4101  int m = *start; 
     4102  while (*start < end) { 
     4103    m = (end+*start)/2; 
     4104    if (id == (*oldList)[m].first) { 
     4105      *start = m; 
     4106      return m; 
     4107    } else { 
     4108      if (id < (*oldList)[m].first) end = m; 
     4109      else *start = m+1; 
     4110    } 
     4111  } 
     4112  return -1;  
     4113} 
     4114 
     4115int GameList::get_current_index_CL(int id, int start) { 
     4116  // use this in between start_sorted() and end_sorted() only! 
     4117  int end = currentList->size(); 
     4118  int m = start; 
     4119  while (start < end) { 
     4120    m = (end+start)/2; 
     4121    if (id == (*currentList)[m].first) return m; 
     4122    else { 
     4123      if (id < (*currentList)[m].first) end = m; 
     4124      else start = m+1; 
     4125    } 
     4126  } 
     4127  return -1;  
    38974128} 
    38984129 
     
    39964227 
    39974228string GameList::currentEntryAsString(int i) { 
    3998   if (i < 0 || i >= (int)currentList->size()) return ""; 
    3999   else return (*all)[(*currentList)[i].second]->gameInfoStr + resultsStr((*all)[(*currentList)[i].second]); 
     4229  if (i < 0 || i >= (int)currentList->size()) { 
     4230    return ""; 
     4231  } else return (*all)[(*currentList)[i].second]->gameInfoStr + resultsStr((*all)[(*currentList)[i].second]); 
    40004232} 
    40014233 
     
    42784510} 
    42794511 
    4280 int GameList::process(const char* sgf, const char* path, const char* fn, const char* DBTREE) throw(SGFError,DBError) { 
     4512int GameList::process(const char* sgf, const char* path, const char* fn, 
     4513                      const char* DBTREE, int flags) throw(SGFError,DBError) { 
     4514  process_results_vector.clear(); 
    42814515  const char* dbtree = ""; 
    42824516  if (DBTREE) dbtree = DBTREE; 
     
    42864520    c = new Cursor(sgf, 1); // parse sgf sloppily 
    42874521  } catch (SGFError) { 
    4288     return 1
     4522    return 0
    42894523  } 
    42904524 
     
    42944528  while (root) { 
    42954529    current++; 
     4530    int return_val = 0; 
    42964531    // if (!(current%1000)) { 
    42974532    //  char* sql = "end transaction;"; 
     
    43194554    if (sz=="") sz = "19"; 
    43204555    int bs = atoi(sz.c_str()); 
     4556    if (bs < 3) {  
     4557      return_val |= UNACCEPTABLE_BOARDSIZE;  
     4558      process_results_vector.push_back(return_val); 
     4559      delete [] rootNodeProperties; 
     4560      root = root->down; 
     4561      pos++; 
     4562      continue; 
     4563    } 
    43214564    int algo_offset = -1; 
    43224565    int bs_ctr = 0; 
     
    44474690    int game_id = sqlite3_last_insert_rowid(db); 
    44484691 
    4449     // evaluate tags 
    4450     if ((*rootNodeProperties)[posHA] != "") { // handicap game 
    4451       char sql[100]; 
    4452       sprintf(sql, "insert into GAME_TAGS (game_id, tag_id) values (%d, %d);", game_id, HANDI_TAG); 
    4453       rc = sqlite3_exec(db, sql, 0, 0, 0); 
    4454       if (rc != SQLITE_OK)  throw DBError(); 
    4455     } 
    4456     if ((*rootNodeProperties)[posWR].find('p') != string::npos || 
    4457         (*rootNodeProperties)[posBR].find('p') != string::npos) {  
    4458       // at least one of the players is professional 
    4459       char sql[100]; 
    4460       sprintf(sql, "insert into GAME_TAGS (game_id, tag_id) values (%d, %d);", game_id, PROFESSIONAL_TAG); 
    4461       rc = sqlite3_exec(db, sql, 0, 0, 0); 
    4462       if (rc != SQLITE_OK)  throw DBError(); 
    4463     } 
    4464  
    4465     delete rootNodeProperties; 
    44664692 
    44674693    // printf("play through the game\n"); 
     4694    bool commit = true; 
    44684695 
    44694696    Node* currentN = root; 
     
    46004827        }  
    46014828      } catch (SGFError) { 
     4829        return_val |= SGF_ERROR; 
    46024830        caughtSGFError = true; 
     4831        if (OMIT_GAMES_WITH_SGF_ERRORS) { 
     4832          commit = false; 
     4833          // (FIXME should exit from the loop here) 
     4834        } 
    46034835      } 
    46044836 
     
    46144846      } 
    46154847 
    4616       if (caughtSGFError) currentN = 0; 
     4848      if (caughtSGFError) currentN = 0; // stop here with this branch 
    46174849      else currentN = currentN->next; 
    46184850 
     
    46344866    } // while 
    46354867    { 
     4868      // check for duplicates (if desired) 
     4869      bool is_duplicate = false; 
     4870      if (flags & (CHECK_FOR_DUPLICATES|CHECK_FOR_DUPLICATES_STRICT)) { 
     4871        char* sig = ((Algo_signature*)algo_ps[20*algo_offset])->get_current_signature(); 
     4872        vector<int> all_duplicates = ((Algo_signature*)algo_ps[20*algo_offset])->search_signature(sig); 
     4873        if (all_duplicates.size()) { 
     4874          // printf("dupl %d\n", all_duplicates.size()); 
     4875          is_duplicate = true; 
     4876          if ((flags & CHECK_FOR_DUPLICATES_STRICT) && (p_op->algos & ALGO_FINALPOS)) { 
     4877            vector<int>::iterator d_it = all_duplicates.begin(); 
     4878            while (d_it != all_duplicates.end() && !((Algo_finalpos*)algo_ps[20*algo_offset + algo_finalpos])->equals_current(*d_it)) 
     4879              d_it++; 
     4880            if (d_it == all_duplicates.end()) is_duplicate = false; 
     4881          } 
     4882          if (is_duplicate) { 
     4883            return_val |= IS_DUPLICATE; 
     4884            if (flags & OMIT_DUPLICATES) commit = false; 
     4885          } 
     4886        } 
     4887        delete [] sig; 
     4888      } 
     4889       
     4890      if (commit) { 
     4891        // evaluate tags 
     4892        if ((*rootNodeProperties)[posHA] != "") { // handicap game 
     4893          char sql[100]; 
     4894          sprintf(sql, "insert into GAME_TAGS (game_id, tag_id) values (%d, %d);", game_id, HANDI_TAG); 
     4895          rc = sqlite3_exec(db, sql, 0, 0, 0); 
     4896          if (rc != SQLITE_OK)  throw DBError(); 
     4897        } 
     4898        if ((*rootNodeProperties)[posWR].find('p') != string::npos || 
     4899            (*rootNodeProperties)[posBR].find('p') != string::npos) {  
     4900          // at least one of the players is professional 
     4901          char sql[100]; 
     4902          sprintf(sql, "insert into GAME_TAGS (game_id, tag_id) values (%d, %d);", game_id, PROFESSIONAL_TAG); 
     4903          rc = sqlite3_exec(db, sql, 0, 0, 0); 
     4904          if (rc != SQLITE_OK)  throw DBError(); 
     4905        } 
     4906      } else { 
     4907        return_val |= NOT_INSERTED_INTO_DB; 
     4908        char sql[200]; 
     4909        sprintf(sql, "delete from GAMES where id=%d", game_id); 
     4910        rc = sqlite3_exec(db, sql, 0, 0, 0); 
     4911        if (rc) printf("ouch %d\n", rc); 
     4912      } 
    46364913      for(int a=20*algo_offset; a < 20*(algo_offset+1); a++) { 
    46374914        // printf("endgame %d\n", a); 
    4638         if (algo_ps[a]) algo_ps[a]->endgame_process(); 
     4915        if (algo_ps[a]) algo_ps[a]->endgame_process(commit); 
    46394916      } 
    46404917    } 
     4918    delete rootNodeProperties; 
     4919    process_results_vector.push_back(return_val); 
    46414920    root = root->down; 
    46424921    pos++; 
    46434922  } 
    46444923  delete c; 
    4645   return 0; // success 
    4646 
     4924  return process_results_vector.size(); 
     4925
     4926 
     4927int GameList::process_results(unsigned int i) { 
     4928  if (i<0 || i>=process_results_vector.size()) return INDEX_OUT_OF_RANGE; 
     4929  return process_results_vector[i]; 
     4930
     4931 
    46474932 
    46484933VarInfo::VarInfo(Node* N, abstractBoard* B, int I) { 
  • 06/libkombilo/search.h

    <
    r230 r239  
    201201    virtual void branchpoint_process(); 
    202202    virtual void endOfVariation_process(); 
    203     virtual void endgame_process(); 
     203    virtual void endgame_process(bool commit=true); 
    204204    virtual void finalize_process(); 
    205205    virtual int readDB(sqlite3* DB); 
     
    225225    void branchpoint_process(); 
    226226    void endOfVariation_process(); 
    227     void endgame_process() throw(DBError); 
     227    void endgame_process(bool commit=true) throw(DBError); 
    228228    void finalize_process(); 
    229229 
    230230    int counter; 
    231231    char* signature; 
     232    char* get_current_signature(); 
     233    std::vector<int> search_signature(char* sig); 
    232234  private: 
    233235    bool main_variation; 
     
    248250    void branchpoint_process(); 
    249251    void endOfVariation_process(); 
    250     void endgame_process() throw(DBError); 
     252    void endgame_process(bool commit=true) throw(DBError); 
    251253    void finalize_process(); 
    252254 
     
    256258    int readDB(sqlite3* DB); 
    257259    int search(PatternList& patternList, GameList& gl, SearchOptions& options); 
     260 
     261    bool equal(unsigned int id1, unsigned int id2); // id1, id2 refer to id's in the database! 
     262    bool equals_current(unsigned int id1); 
    258263}; 
    259264 
     
    317322    void branchpoint_process(); 
    318323    void endOfVariation_process(); 
    319     void endgame_process() throw(DBError); 
     324    void endgame_process(bool commit=true) throw(DBError); 
    320325    void finalize_process(); 
    321326    int readDB(sqlite3* DB); 
     
    329334}; 
    330335 
     336class HashFEntry { 
     337  public: 
     338    hashtype hashCode; 
     339    char* buf; 
     340    int length; 
     341 
     342    HashFEntry(hashtype HASHCODE, char* BUF, int LENGTH); 
     343    HashFEntry(const HashFEntry& hfe); 
     344    ~HashFEntry(); 
     345}; 
    331346 
    332347class HashhitF { // hashing hit for full board search 
     
    374389    void branchpoint_process(); 
    375390    void endOfVariation_process() throw(DBError); 
    376     void endgame_process() throw(DBError); 
     391    void endgame_process(bool commit=true) throw(DBError); 
    377392    void finalize_process(); 
    378393    int search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db); 
    379394 
    380     int insert_hash(hashtype hashCode, ExtendedMoveNumber& mn, Move* continuation); 
    381395    hashtype compute_hashkey(Pattern& pattern); 
    382396 
     397    int maxNumStones; 
     398    int numStones; 
     399  private: 
    383400    hashtype currentHashCode; 
    384401    ExtendedMoveNumber* moveNumber; 
    385402    std::vector<std::pair<hashtype, ExtendedMoveNumber>* > *lfc; // hash code + move number, still looking for continuation 
    386403    std::stack<HashVarInfo>* branchpoints; 
    387     int maxNumStones; 
    388     int numStones; 
     404    int insert_hash(hashtype hashCode, ExtendedMoveNumber& mn, Move* continuation); 
     405    int insert_all_hashes(); 
     406    std::vector<HashFEntry> hash_vector; 
    389407}; 
    390408 
     
    439457    virtual void branchpoint_process(); 
    440458    virtual void endOfVariation_process(); 
    441     virtual void endgame_process(); 
     459    virtual void endgame_process(bool commit=true); 
    442460    virtual void finalize_process(); 
    443461    virtual int search(PatternList& patternList, GameList& gl, SearchOptions& options, sqlite3* db); 
    444462 
     463    virtual std::pair<hashtype,int> compute_hashkey(PatternList& pl, int CS); 
     464    static const hashtype hashCodes[]; 
     465    std::string dbnameext; 
     466    std::vector<HashInstance>* hi; 
     467    int maxNumStones; 
     468    std::vector<std::pair<hashtype, int> > hash_vector; 
    445469    virtual int insert_hash(hashtype hashCod, int pos); 
    446     virtual std::pair<hashtype,int> compute_hashkey(PatternList& pl, int CS); 
    447     std::vector<HashInstance>* hi; 
    448     std::string dbnameext; 
    449     int maxNumStones; 
    450  
    451     static const hashtype hashCodes[]; 
     470    int insert_all_hashes(); 
    452471}; 
    453472 
     
    569588    ~VarInfo(); 
    570589}; 
     590 
     591// process flags (used to determine the behavior for individual games - in contrast to 
     592// options which apply to the whole GameList and are given in ProcessOptions) 
     593const int CHECK_FOR_DUPLICATES = 1; // check for duplicates using the signature 
     594const int CHECK_FOR_DUPLICATES_STRICT = 2; // check for duplicates using the final position 
     595                                           // (if ALGO_FINAPOS is available) 
     596const int OMIT_DUPLICATES = 4; 
     597const int OMIT_GAMES_WITH_SGF_ERRORS = 8;  
     598const int INDEX_OUT_OF_RANGE = 16; 
     599 
     600// process return values 
     601// 0:   SGF error occurred when parsing the "tree structure" (i.e. before parsing the individual nodes) 
     602//      database was not changed 
     603// n>0: n games were processed, use process_results to access the individual results  
     604 
     605// flags used in process_results 
     606const int UNACCEPTABLE_BOARDSIZE = 1; // (database not changed)  
     607const int SGF_ERROR = 2; 
     608    // SGF error occurred when playing through the game  
     609    // (and the rest of the concerning variation was not used). 
     610    // Depending on OMIT_GAMES_WITH_SGF_ERRORS, everything before this node (and other variations,  
     611    // if any) was inserted, or the database was not changed. 
     612const int IS_DUPLICATE = 4; 
     613const int NOT_INSERTED_INTO_DB = 8; 
     614 
    571615 
    572616class GameList { 
     
    606650    // ------- processing SGF games (to populate the db) -------------------------- 
    607651    void start_processing(int PROCESSVARIATIONS=-1) throw(DBError); 
    608     int process(const char* sgf, const char* path, const char* fn, const char* DBTREE = 0) throw(SGFError,DBError); 
     652    int process(const char* sgf, const char* path, const char* fn, 
     653                const char* DBTREE = 0, int flags=0) throw(SGFError,DBError); 
     654    int process_results(unsigned int i=0); // result for i-th processed game in most recently processed SGF collection 
    609655    void finalize_processing() throw(DBError); 
    610656     
     657    // int remove_game(int index); // TODO 
     658    // int remove_all_current_games(); 
     659 
    611660    // ------- pattern search ----------------------------------------------------- 
    612661    // options is copied in the search method (if != 0), so the caller has to free the pointer 
     
    629678    void deleteTag(int tag, int i = -1) throw(DBError); 
    630679    std::vector<int> getTags(int i, int tag=0) throw(DBError); // note the order of arguments! 
     680     
     681    // ------- duplicates --------------------------------------------------------- 
     682    int find_duplicates(int bs, bool strict=false) throw(DBError); // return number of duplicate array 
     683    std::vector<int> retrieve_duplicates_VI(unsigned int i); 
     684    int* retrieve_duplicates_PI(unsigned int i); // same as above, but returns Pointer to Int  
     685                                                 // (an array terminated by -1) 
     686                                                 // The caller must free the pointer himself 
     687                                                 // (before calling find_duplicates again). 
    631688 
    632689    // ------- misc --------------------------------------------------------------- 
     
    659716    void makeIndexHit(int index, std::vector<Hit* > *hits); 
    660717    void setCurrentFromIndex(int index); 
     718