From 5e68166525951a0c2b59e993c43c2850cbb99008 Mon Sep 17 00:00:00 2001 From: NguyenPham Date: Tue, 25 Jan 2022 12:26:29 +1100 Subject: [PATCH] Version beta --- README.md | 51 ++- .../UserInterfaceState.xcuserstate | Bin 134019 -> 138418 bytes .../xcshareddata/xcschemes/ocgdb.xcscheme | 14 +- .../xcdebugger/Breakpoints_v2.xcbkptlist | 374 ++++++++++++--- src/board/base.cpp | 33 ++ src/board/base.h | 17 +- src/board/chess.h | 2 +- src/builder.cpp | 429 +++++++++++------- src/builder.h | 73 ++- src/main.cpp | 112 ++--- 10 files changed, 759 insertions(+), 346 deletions(-) diff --git a/README.md b/README.md index e5584b3..186b5ec 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,23 @@ # Open Chess Game Database Standard (OCGDB) -Version Alpha +Version Beta -## Features/Highlights of the Standard -- Developed based on SQL in general, SQLite in particular -- It has an open data structure: very easy to understand, change, convert to/from other formats -- Terms, names, types… are followed PGN standard as much as possible -- Basic tables: Games, Events, Sites, Players, Comments. Other tables: Info -- Main columns of the table Games: EvenID, SiteID, WhiteID, WhiteElo, BlackID, Result, Date, ECO, FEN, Moves/Moves1/Moves2 -- FEN (in the table Games) is for the starting position. If the game started from origin position, it could be empty or NULL -- Moves are stored in table Games with a few choices: as text in column Moves, or binary forms in column Moves1 (for 1-byte encoding) or column Moves2 (for 2-bytes encoding) -- It could query game header information via SQL/SQL search engines -- It could do approximate-position-searching with the support from the belonging code and Position Query Language (PQL) -- There are no or very high limit about the number of games. Some tests show it worked well with databases of over 90 million games and could work with much larger numbers -- It could serve for any purposes of chess game databases from web to desktop, mobiphone apps +## Brief main ideas/techniques +- Use SQL/SQLite as the backbone/framework for storing data and querying general information +- Approximate position searching: a) Parse games on the fly b) Use Position Query Language (PQL) for querying widely and dynamically +- Names, tables follow to PGN tags + + +## Why OCGDB? Features/Highlights +- Open databases: users could easily understand data structures, modify, convert to or from other database formats +- It supports the highest numbers of games (tested with 94 million games, estimated it could work with billions of games) +- It is based on SQL which is the strongest query language for querying general information. Users can query without using chess specific programs +- It has its own query language (PQL) for approximate-position-searching thus it can cover very widely +- It could use widely, from mobile, desktop, console to web applications  +- It is one of programs that could create the smallest chess game databases +- It is one of the fastest chess game database programs when generating databases and searching +- MIT license: you may use it for any applications/purposes unlimitedly without worrying about license conditions We believe it is one of the fastest (in terms of speeds of creating and querying/searching), smallest (in terms of database sizes), strongest (in terms of game numbers), and smartest (in terms of querying/position-searching) chess game database programs. It could compete for all parameters, results with the best chess game database formats and their programs/tools. @@ -137,6 +140,27 @@ Convert a PGN file of 94 million games from Lichess: #games: 93679650, elapsed: 5209214ms 1:26:49, speed: 17983 games/s, #blocks: 25777, processed size: 206208 MB ``` +## Retrieve data +Query database and extract some important data fields: + +``` +for (auto cnt = 0; statement.executeStep(); cnt++) { + auto gameID = statement.getColumn("ID").getInt64(); assert(gameID > 0); + auto fenText = statement.getColumn("FEN").getText(); + auto moveText = statement.getColumn("Moves").getText(); +} +``` + +Query database, extract some data fields and parse into chessboard, using multi-threads: +``` +for auto cnt = 0; statement.executeStep(); cnt++) { + auto gameID = statement.getColumn("ID").getInt64(); + auto fenText = statement.getColumn("FEN").getText(); + auto moveText = statement.getColumn("Moves").getText(); + threadParsePGNGame(gameID, fenText, moveText); +} +``` + ## Position query language (PQL) The EBNF (Extended Backus Naur Form) of the language is as the below: @@ -264,6 +288,7 @@ ocgdb -db c:\db\big.ocgdb.db3 -cpu 4 -q "Q=3" -q"P[d4, e5, f4, g4] = 4 and kb7" ``` ## History +* 25/01/2022: Version Beta * 23/01/2022: Version Alpha * 20/11/2021: Improve/clean code, improve speed for benchmark * 16/11/2021: Improve speed for converter, convert 3.45 million games under a minute diff --git a/projects/ocgdb.xcodeproj/project.xcworkspace/xcuserdata/nguyenpham.xcuserdatad/UserInterfaceState.xcuserstate b/projects/ocgdb.xcodeproj/project.xcworkspace/xcuserdata/nguyenpham.xcuserdatad/UserInterfaceState.xcuserstate index 84c28b458d24ba7dd7b89db52bd16e8c1fc3f55f..c5d37f205f4a2a825f621b5d4d5ebd2425b4f5c1 100644 GIT binary patch literal 138418 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 er!Xz}zyIO?M&Q`Tql$+s&~6 diff --git a/projects/ocgdb.xcodeproj/xcshareddata/xcschemes/ocgdb.xcscheme b/projects/ocgdb.xcodeproj/xcshareddata/xcschemes/ocgdb.xcscheme index 9354539..deca944 100644 --- a/projects/ocgdb.xcodeproj/xcshareddata/xcschemes/ocgdb.xcscheme +++ b/projects/ocgdb.xcodeproj/xcshareddata/xcschemes/ocgdb.xcscheme @@ -65,7 +65,7 @@ + isEnabled = "YES"> + isEnabled = "NO"> + isEnabled = "YES"> + + @@ -115,6 +119,10 @@ argument = "-cpu 1" isEnabled = "NO"> + + @@ -414,8 +414,8 @@ filePath = "../src/board/base.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "950" - endingLineNumber = "950" + startingLineNumber = "957" + endingLineNumber = "957" landmarkName = "BoardCore::fromMoveList(gameId, moveVec, flag, shouldStop)" landmarkType = "7"> @@ -510,8 +510,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "727" - endingLineNumber = "727" + startingLineNumber = "721" + endingLineNumber = "721" landmarkName = "Builder::createDb(path)" landmarkType = "7"> @@ -526,8 +526,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "725" - endingLineNumber = "725" + startingLineNumber = "719" + endingLineNumber = "719" landmarkName = "Builder::createDb(path)" landmarkType = "7"> @@ -542,8 +542,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "440" - endingLineNumber = "440" + startingLineNumber = "430" + endingLineNumber = "430" landmarkName = "Builder::addNewField(fieldName)" landmarkType = "7"> @@ -558,8 +558,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1120" - endingLineNumber = "1120" + startingLineNumber = "1139" + endingLineNumber = "1139" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> @@ -574,8 +574,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1125" - endingLineNumber = "1125" + startingLineNumber = "1144" + endingLineNumber = "1144" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> @@ -590,28 +590,12 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1146" - endingLineNumber = "1146" + startingLineNumber = "1165" + endingLineNumber = "1165" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> - - - - @@ -638,8 +622,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1027" - endingLineNumber = "1027" + startingLineNumber = "1041" + endingLineNumber = "1041" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> @@ -654,8 +638,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1023" - endingLineNumber = "1023" + startingLineNumber = "1037" + endingLineNumber = "1037" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> @@ -670,8 +654,8 @@ filePath = "../src/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "77" - endingLineNumber = "77" + startingLineNumber = "75" + endingLineNumber = "75" landmarkName = "main(argc, argv)" landmarkType = "9"> @@ -686,8 +670,8 @@ filePath = "../src/main.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "76" - endingLineNumber = "76" + startingLineNumber = "74" + endingLineNumber = "74" landmarkName = "main(argc, argv)" landmarkType = "9"> @@ -702,9 +686,9 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "1342" - endingLineNumber = "1342" - landmarkName = "Builder::searchPosition(db, query)" + startingLineNumber = "1402" + endingLineNumber = "1402" + landmarkName = "Builder::searchPosition(db, pgnPaths, query)" landmarkType = "7"> @@ -718,8 +702,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "931" - endingLineNumber = "931" + startingLineNumber = "942" + endingLineNumber = "942" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> @@ -734,8 +718,8 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "932" - endingLineNumber = "932" + startingLineNumber = "943" + endingLineNumber = "943" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> @@ -750,11 +734,299 @@ filePath = "../src/builder.cpp" startingColumnNumber = "9223372036854775807" endingColumnNumber = "9223372036854775807" - startingLineNumber = "941" - endingLineNumber = "941" + startingLineNumber = "952" + endingLineNumber = "952" landmarkName = "Builder::addGame(itemMap, moveText)" landmarkType = "7"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/board/base.cpp b/src/board/base.cpp index e5db156..876fb90 100644 --- a/src/board/base.cpp +++ b/src/board/base.cpp @@ -887,6 +887,13 @@ bool BoardCore::fromMoveList(int64_t gameId, const std::string& str, Notation no histList.back().bitboardVec = bitboardVec; } + if (flag & ParseMoveListFlag_create_san) { + if (notation == Notation::san) { + histList.back().sanString = ss; + } else { + // missing function + } + } } // last position @@ -1083,6 +1090,32 @@ std::string BoardCore::toSimplePgn() const return stringStream.str(); } +std::string BoardCore::toPgn(const std::unordered_map tags) const +{ + std::ostringstream stringStream; + + auto it = tags.find("Event"); + stringStream << "[Event \"" + << (it != tags.end() ? it->second : "event") + << "\"]\n"; + + for(auto && it : tags) { + if (it.first != "Event") { + stringStream << "[" << it.first << "\"" + << it.second + << "\"]\n"; + } + } + if (!startFen.empty()) { + stringStream << "[FEN \"" << startFen << "\"]\n"; + } + + stringStream << "\n" << toMoveListString(Notation::san, + 8, true, + CommentComputerInfoType::standard); + return stringStream.str(); +} + void BoardCore::flip(FlipMode flipMode) { diff --git a/src/board/base.h b/src/board/base.h index 59aecfb..5cef2a3 100644 --- a/src/board/base.h +++ b/src/board/base.h @@ -13,6 +13,7 @@ #include #include +#include #include // for setfill, setw @@ -224,6 +225,10 @@ namespace bslib { result.result = ResultType::noresult; } + virtual std::string toString() const { + return ""; + } + bool isValid(const Move& move) const { return move.isValid() && isPositionValid(move.from) && isPositionValid(move.dest); } @@ -363,12 +368,13 @@ namespace bslib { enum ParseMoveListFlag { ParseMoveListFlag_quick_check = 1 << 0, - ParseMoveListFlag_create_fen = 1 << 1, - ParseMoveListFlag_create_bitboard = 1 << 2, - ParseMoveListFlag_discardComment = 1 << 3, - ParseMoveListFlag_parseComment = 1 << 4, + ParseMoveListFlag_create_san = 1 << 1, + ParseMoveListFlag_create_fen = 1 << 2, + ParseMoveListFlag_create_bitboard = 1 << 3, + ParseMoveListFlag_discardComment = 1 << 4, + ParseMoveListFlag_parseComment = 1 << 5, - ParseMoveListFlag_move_size_1_byte = 1 << 5, // for the 2nd function one only + ParseMoveListFlag_move_size_1_byte = 1 << 6, // for the 2nd function one only }; virtual bool fromMoveList(int64_t gameId, const std::string&, Notation, int flag, std::function& bitboardVec, const BoardCore*)> = nullptr); @@ -386,6 +392,7 @@ namespace bslib { static std::string toMoveListString(const std::vector& histList, ChessVariant variant, Notation notation, int itemPerLine, bool moveCounter, CommentComputerInfoType computingInfo, bool pawnUnit, int precision); virtual std::string toSimplePgn() const; + virtual std::string toPgn(const std::unordered_map tags) const; virtual int16_t move2i16(int from, int dest, int promotion, bool haveComment) const = 0; virtual void i16ToMove(int data, int& from, int& dest, int& promotion, bool& haveComment) const = 0; diff --git a/src/board/chess.h b/src/board/chess.h index 4b20480..fbad4c4 100644 --- a/src/board/chess.h +++ b/src/board/chess.h @@ -32,7 +32,7 @@ namespace bslib { ChessBoard(const ChessBoard&); virtual ~ChessBoard() override; - virtual std::string toString() const; + virtual std::string toString() const override; virtual bool isValid() const override; virtual int columnCount() const override; diff --git a/src/builder.cpp b/src/builder.cpp index 1b59223..b98e87f 100644 --- a/src/builder.cpp +++ b/src/builder.cpp @@ -29,29 +29,29 @@ Builder* builder = nullptr; bool ParaRecord::isValid() const { - if (dbPath.empty()) { + if (dbPath.empty() && task != Task::query) { errorString = "Must have a database (.db3) path. Mising or wrong parameter -db"; return false; } + auto hasPgn = false; + for(auto && s : pgnPaths) { + if (!s.empty()) { + hasPgn = true; + break; + } + } + errorString.clear(); auto ok = false; switch (task) { - case Task::createSQLdatabase: + case Task::create: { if (cpuNumber <= 0) { errorString = "CPU number must be greater than zero"; break; } - auto hasPgn = false; - for(auto && s : pgnPaths) { - if (!s.empty()) { - hasPgn = true; - break; - } - } - if (!hasPgn) { errorString = "Must have at least one PGN path. Mising or wrong parameter -pgn"; break; @@ -62,6 +62,10 @@ bool ParaRecord::isValid() const } case Task::query: + if (dbPath.empty() && !hasPgn) { + errorString = "Must have a database (.db3) path or a PGN path. Mising or wrong parameter -db and -pgn"; + return false; + } if (queries.empty()) { errorString = "Must have at least one query. Mising or wrong parameter -q"; break; @@ -83,6 +87,21 @@ bool ParaRecord::isValid() const return ok; } +static const std::map optionNameMap = { + // creating + {"moves", 0}, + {"moves1", 1}, + {"moves2", 2}, + {"acceptnewtags", 3}, + {"discardcomments", 4}, + {"discardsites", 5}, + {"discardnoelo", 6}, + // query + {"printall", 7}, + {"printfen", 8}, + {"printpgn", 9}, +}; + std::string ParaRecord::toString() const { std::string s; @@ -93,19 +112,7 @@ std::string ParaRecord::toString() const "bench" }; - - const std::string optionNames[] = { - "comment_discard", - "site_discard", - "accept_newTags", - "player_limit_elo", - "player_discard_no_elo", - "query_stop_at_first_result", - "query_print_all", - "query_print_fen", - "query_print_pgn", - }; - + s = "\tTask: " + taskNames[static_cast(task)] + "\n"; s += "\tPGN paths:\n"; @@ -125,20 +132,42 @@ std::string ParaRecord::toString() const "Moves", "Moves1", "Moves2", "Moves + Moves1", "Moves + Moves2" }; - s += "\tMove columns (for creating): " + moveModeNames[static_cast(columnMovesMode)] + "\n"; s += "\tOptions: "; - for(auto && o : optionSet) { - s += optionNames[static_cast(o)] + "; "; + for(auto && it : optionNameMap) { + if (optionFlag & (1 << it.second)) { + s += it.first + ";"; + } } + s += "\n"; - s += "\tgameNumberLimit: " + std::to_string(gameNumberLimit) + "\n"; - s += "\tcpu: " + std::to_string(cpuNumber) + ", low Elo: " + std::to_string(lowElo) + "\n"; - + s += "\tgameNumberLimit: " + std::to_string(gameNumberLimit) + "\n" + + "\tresultNumberLimit: " + std::to_string(resultNumberLimit) + "\n" + + "\tcpu: " + std::to_string(cpuNumber) + + ", min Elo: " + std::to_string(limitElo) + + ", min game length: " + std::to_string(limitLen) + + "\n"; + return s; } + +void ParaRecord::setupOptions(const std::string& optionString) +{ + optionFlag = 0; + auto vec = bslib::Funcs::splitString(optionString, ';'); + + for(auto && s : vec) { + auto it = optionNameMap.find(s); + if (it == optionNameMap.end()) { + std::cerr << "Error: Don't know option string: " << it->first << std::endl; + } else { + optionFlag |= 1 << it->second; + } + } +} + static const char* tagNames[] = { "GameID", // Not real PGN tag, added for convernience @@ -166,12 +195,12 @@ void ThreadRecord::init(SQLite::Database* mDb) errCnt = 0; - assert(mDb); board = Builder::createBoard(bslib::ChessVariant::standard); - - insertCommentStatement = new SQLite::Statement(*mDb, "INSERT INTO Comments (GameID, Ply, Comment) VALUES (?, ?, ?)"); - buf = new int8_t[1024 * 2]; + + if (mDb) { + insertCommentStatement = new SQLite::Statement(*mDb, "INSERT INTO Comments (GameID, Ply, Comment) VALUES (?, ?, ?)"); + } } ThreadRecord::~ThreadRecord() @@ -255,14 +284,14 @@ bslib::BoardCore* Builder::createBoard(bslib::ChessVariant variant) void Builder::runTask(const ParaRecord& param) { switch (param.task) { - case Task::createSQLdatabase: + case Task::create: convertPgn2Sql(param); break; case Task::bench: - bench(param.dbPath, param.cpuNumber, param.optionSet); + bench(param); break; case Task::query: - query(param.dbPath, param.cpuNumber, param.queries, param.optionSet); + query(param, param.queries); break; default: @@ -270,7 +299,7 @@ void Builder::runTask(const ParaRecord& param) } } -void Builder::convertPgn2Sql(const ParaRecord& paraRecord) +void Builder::convertPgn2Sql(const ParaRecord& _paraRecord) { // Prepare setDatabasePath(paraRecord.dbPath); @@ -279,47 +308,21 @@ void Builder::convertPgn2Sql(const ParaRecord& paraRecord) std::remove(paraRecord.dbPath.c_str()); startTime = getNow(); - + // options { - createoption_AcceptNewField = paraRecord.optionSet.find(Option::accept_newTags) != paraRecord.optionSet.end(); - createoption_site_discard = paraRecord.optionSet.find(Option::site_discard) != paraRecord.optionSet.end(); - createoption_comment_discard = paraRecord.optionSet.find(Option::comment_discard) != paraRecord.optionSet.end(); + paraRecord = _paraRecord; - createoption_elo_limit = paraRecord.optionSet.find(Option::player_limit_elo) != paraRecord.optionSet.end(); - createoption_elo_discard_no_elo = paraRecord.optionSet.find(Option::player_discard_no_elo) != paraRecord.optionSet.end(); - - createoption_KeepMovesField = false; - createoption_EncodeMoveSize = 0; + int movebit = paraRecord.optionFlag & (create_flag_moves|create_flag_moves1|create_flag_moves2); - switch (paraRecord.columnMovesMode) { - case ColumnMovesMode::moves: - createoption_KeepMovesField = true; - break; - case ColumnMovesMode::moves1: - createoption_EncodeMoveSize = 1; - break; - case ColumnMovesMode::moves2: - createoption_EncodeMoveSize = 2; - break; - case ColumnMovesMode::moves_moves1: - createoption_KeepMovesField = true; - createoption_EncodeMoveSize = 1; - break; - case ColumnMovesMode::moves_moves2: - createoption_KeepMovesField = true; - createoption_EncodeMoveSize = 2; - break; - - default: - break; - } - - createoption_gameNumberLimit = paraRecord.gameNumberLimit; - createoption_lowElo = paraRecord.lowElo; - - if (!createoption_KeepMovesField && createoption_EncodeMoveSize != 1 && createoption_EncodeMoveSize != 2) { + if (!movebit) { std::cout << "WARNING: there is not any column for storing moves" << std::endl; + } else if (movebit != create_flag_moves && movebit != create_flag_moves1 && movebit != create_flag_moves2) { + std::cout << "WARNING: redundant! There are more than one column for storing moves" << std::endl; + + if ((paraRecord.optionFlag & (create_flag_moves1 | create_flag_moves2)) == (create_flag_moves1 | create_flag_moves2)) { + std::cout << "WARNING: redundant! There are two binary columns for storing moves. Use Moves2, discard Move1" << std::endl; + } } } @@ -328,12 +331,11 @@ void Builder::convertPgn2Sql(const ParaRecord& paraRecord) { gameCnt = 0; eventCnt = playerCnt = siteCnt = 1; - errCnt = posCnt = 0; - - auto cpu = paraRecord.cpuNumber; - if (cpu < 0) cpu = std::thread::hardware_concurrency(); - pool = new thread_pool(cpu); + errCnt = 0; + playerIdMap.reserve(8 * 1024 * 1024); + eventIdMap.reserve(128 * 1024); + siteIdMap.reserve(128 * 1024); extraFieldSet.clear(); fieldOrderMap.clear(); @@ -346,23 +348,19 @@ void Builder::convertPgn2Sql(const ParaRecord& paraRecord) fieldOrderMap["UTCDate"] = TagIdx_Date; tagIdx_Moves = -1; tagIdx_MovesBlob = -1; - if (createoption_KeepMovesField) { + if (paraRecord.optionFlag & create_flag_moves) { tagIdx_Moves = idx++; fieldOrderMap["Moves"] = tagIdx_Moves; extraFieldSet.insert("Moves"); } - if (createoption_EncodeMoveSize == 1 || createoption_EncodeMoveSize == 2) { + if (paraRecord.optionFlag & (create_flag_moves1 | create_flag_moves2)) { tagIdx_MovesBlob = idx++; - std::string s = "Moves" + std::to_string(createoption_EncodeMoveSize); + std::string s = (paraRecord.optionFlag & create_flag_moves2) ? "Moves2" : "Moves1"; fieldOrderMap[s] = tagIdx_MovesBlob; extraFieldSet.insert(s); } insertGameStatementIdxSz = idx; - playerIdMap.reserve(8 * 1024 * 1024); - eventIdMap.reserve(128 * 1024); - siteIdMap.reserve(128 * 1024); - // Create database mDb = createDb(paraRecord.dbPath); @@ -370,19 +368,11 @@ void Builder::convertPgn2Sql(const ParaRecord& paraRecord) return; } - // prepared statements - playerInsertStatement = new SQLite::Statement(*mDb, "INSERT INTO Players (ID, Name, Elo) VALUES (?, ?, ?)"); - eventInsertStatement = new SQLite::Statement(*mDb, "INSERT INTO Events (ID, Name) VALUES (?, ?)"); - siteInsertStatement = new SQLite::Statement(*mDb, "INSERT INTO Sites (ID, Name) VALUES (?, ?)"); - - std::cout << "Thread count: " << pool->get_thread_count() - << std::endl; + auto cpu = paraRecord.cpuNumber; + if (cpu < 0) cpu = std::thread::hardware_concurrency(); + pool = new thread_pool(cpu); - std::cout << "Move encoding size: " - << createoption_EncodeMoveSize - << (createoption_KeepMovesField ? ", keep field Moves" : " without field Moves") - << std::endl; - + std::cout << "Thread count: " << pool->get_thread_count() << std::endl; } uint64_t cnt = 0; @@ -522,7 +512,12 @@ void Builder::processDataBlock(char* buffer, long sz, bool connectBlock) if (hasEvent && p - buffer > 2) { *(p - 2) = 0; - threadAddGame(tagMap, moves); +// threadAddGame(tagMap, moves); + if (paraRecord.task == Task::create) { + threadAddGame(tagMap, moves); + } else { + threadQueryGame(tagMap, moves); + } } tagMap.clear(); @@ -597,16 +592,18 @@ void Builder::processDataBlock(char* buffer, long sz, bool connectBlock) if (connectBlock) { processHalfBegin(event, (long)sz - (event - buffer)); } else if (moves) { - threadAddGame(tagMap, moves); + if (paraRecord.task == Task::create) { + threadAddGame(tagMap, moves); + } else { + threadQueryGame(tagMap, moves); + } } } uint64_t Builder::processPgnFile(const std::string& path) { std::cout << "Processing PGN file: '" << path << "'" << std::endl; - - // Begin transaction -// SQLite::Transaction transaction(*mDb); + auto transactionCnt = 0; { @@ -617,7 +614,7 @@ uint64_t Builder::processPgnFile(const std::string& path) auto size = bslib::Funcs::getFileSize(stream); blockCnt = processedPgnSz = 0; - for (size_t sz = 0, idx = 0; sz < size && gameCnt < createoption_gameNumberLimit; idx++) { + for (size_t sz = 0, idx = 0; sz < size && gameCnt < paraRecord.gameNumberLimit; idx++) { auto k = std::min(blockSz, size - sz); if (k == 0) { break; @@ -625,7 +622,7 @@ uint64_t Builder::processPgnFile(const std::string& path) buffer[k] = 0; if (fread(buffer, k, 1, stream)) { - if (transactionCnt <= 0) { + if (mDb && transactionCnt <= 0) { transactionCnt = 400; mDb->exec("BEGIN"); std::cout << "BEGIN TRANSACTION" << std::endl; @@ -637,7 +634,7 @@ uint64_t Builder::processPgnFile(const std::string& path) pool->wait_for_tasks(); transactionCnt--; - if (transactionCnt <= 0) { + if (mDb && transactionCnt <= 0) { mDb->exec("COMMIT"); std::cout << "COMMIT TRANSACTION" << std::endl; } @@ -663,13 +660,10 @@ uint64_t Builder::processPgnFile(const std::string& path) } } - if (transactionCnt > 0) { + if (mDb && transactionCnt > 0) { mDb->exec("COMMIT"); } - // Commit transaction -// transaction.commit(); - printStats(); return gameCnt; @@ -733,11 +727,12 @@ SQLite::Database* Builder::createDb(const std::string& path) "Date TEXT, Round INTEGER, WhiteID INTEGER, WhiteElo INTEGER, BlackID INTEGER, BlackElo INTEGER, "\ "Result INTEGER, TimeControl TEXT, ECO TEXT, PlyCount INTEGER, FEN TEXT"; - if (createoption_KeepMovesField) { + if (paraRecord.optionFlag & create_flag_moves) { sqlstring0 += ", Moves TEXT"; } - if (createoption_EncodeMoveSize == 1 || createoption_EncodeMoveSize == 2) { - sqlstring0 += ", Moves" + std::to_string(createoption_EncodeMoveSize) + " BLOB DEFAULT NULL"; + if (paraRecord.optionFlag & (create_flag_moves1 | create_flag_moves2)) { + auto sz = (paraRecord.optionFlag & create_flag_moves2) ? 2 : 1; + sqlstring0 += ", Moves" + std::to_string(sz) + " BLOB DEFAULT NULL"; } std::string sqlstring1 = @@ -754,6 +749,11 @@ SQLite::Database* Builder::createDb(const std::string& path) // mDb->exec("PRAGMA synchronous=OFF"); // mDb->exec("PRAGMA cache_size=64000"); + // prepared statements + playerInsertStatement = new SQLite::Statement(*mDb, "INSERT INTO Players (ID, Name, Elo) VALUES (?, ?, ?)"); + eventInsertStatement = new SQLite::Statement(*mDb, "INSERT INTO Events (ID, Name) VALUES (?, ?)"); + siteInsertStatement = new SQLite::Statement(*mDb, "INSERT INTO Sites (ID, Name) VALUES (?, ?)"); + return mDb; } catch (std::exception& e) @@ -851,11 +851,22 @@ void doAddGame(const std::unordered_map& itemMap, const char* move builder->addGame(itemMap, moveText); } +void doQueryGame(const std::unordered_map& itemMap, const char* moveText) +{ + assert(builder); + builder->queryGame(itemMap, moveText); +} + void Builder::threadAddGame(const std::unordered_map& itemMap, const char* moveText) { pool->submit(doAddGame, itemMap, moveText); } +void Builder::threadQueryGame(const std::unordered_map& itemMap, const char* moveText) +{ + pool->submit(doQueryGame, itemMap, moveText); +} + static void standardizeDate(char* date) { assert(date); @@ -914,7 +925,7 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha } case TagIdx_Site: { - if (createoption_site_discard) { + if (paraRecord.optionFlag & create_flag_discard_sites) { intMap[TagIdx_Site] = 1; // empty break; } @@ -981,6 +992,9 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha case TagIdx_PlyCount: { plyCount = std::atoi(s); + if (paraRecord.limitLen > plyCount) { + return false; + } break; } @@ -1019,15 +1033,15 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha } } - if (createoption_elo_discard_no_elo && (whiteElo <= 0 || blackElo <= 0)) { + if ((paraRecord.optionFlag & create_flag_discard_no_elo) && (whiteElo <= 0 || blackElo <= 0)) { return false; } - if (createoption_elo_limit && (whiteElo < createoption_lowElo || blackElo < createoption_lowElo)) { + if (paraRecord.limitElo > 0 && (whiteElo < paraRecord.limitElo || blackElo < paraRecord.limitElo)) { return false; } - if (createoption_AcceptNewField && strcmp(it.first, "SetUp") != 0) { + if ((paraRecord.optionFlag & create_flag_accept_new_tags) && strcmp(it.first, "SetUp") != 0) { if (t->insertGameStatement) { delete t->insertGameStatement; t->insertGameStatement = nullptr; @@ -1061,7 +1075,7 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha intMap[TagIdx_GameID] = gameID; if (tagIdx_Moves >= 0) { - assert(createoption_KeepMovesField); + assert(paraRecord.optionFlag & create_flag_moves); // trim left while(*moveText <= ' ') moveText++; @@ -1070,26 +1084,34 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha // Parse moves if (tagIdx_MovesBlob >= 0) { - assert(createoption_EncodeMoveSize == 1 || createoption_EncodeMoveSize == 2); + assert(paraRecord.optionFlag & (create_flag_moves1 | create_flag_moves2)); //assert(t->board); t->board->newGame(fenString); int flag = bslib::BoardCore::ParseMoveListFlag_quick_check; - if (createoption_comment_discard) { + if (paraRecord.optionFlag & create_flag_discard_comments) { flag |= bslib::BoardCore::ParseMoveListFlag_discardComment; } t->board->fromMoveList(gameID, moveText, bslib::Notation::san, flag); plyCount = t->board->getHistListSize(); + + if (paraRecord.limitLen > plyCount) { + return false; + } + if (plyCount > 0) { auto p = t->buf; for(auto i = 0; i < plyCount; i++) { auto h = t->board->_getHistPointerAt(i); auto move = h->move; - if (createoption_EncodeMoveSize == 1) { + if (paraRecord.optionFlag & create_flag_moves2) { // 2 bytes encoding + *(int16_t*)p = bslib::ChessBoard::encode2Bytes(move); + p += 2; + } else if (paraRecord.optionFlag & create_flag_moves1) { auto pair = bslib::ChessBoard::encode1Byte(move); assert(pair.second == 1 || pair.second == 2); if (pair.second == 1) { @@ -1101,9 +1123,6 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha assert(*(p + 1) == static_cast(pair.first >> 8)); p += 2; } - } else if (createoption_EncodeMoveSize == 2) { // 2 bytes encoding - *(int16_t*)p = bslib::ChessBoard::encode2Bytes(move); - p += 2; } if (!h->comment.empty()) { @@ -1149,6 +1168,46 @@ bool Builder::addGame(const std::unordered_map& itemMap, const cha return true; } +bool Builder::queryGame(const std::unordered_map& itemMap, const char* moveText) +{ + auto threadId = std::this_thread::get_id(); + auto t = &threadMap[threadId]; + t->init(mDb); + assert(t->board); + + std::string fenString; + for(auto && it : itemMap) { + if (strcmp(it.first, "FEN") == 0) { + fenString = it.second; + break; + } + } + + IDInteger gameID; + { + std::lock_guard dolock(gameMutex); + ++gameCnt; + gameID = gameCnt; + } + + // Parse moves + { + //assert(t->board); + t->board->newGame(fenString); + + int flag = bslib::BoardCore::ParseMoveListFlag_quick_check + | bslib::BoardCore::ParseMoveListFlag_discardComment + | bslib::BoardCore::ParseMoveListFlag_create_bitboard; + + if (paraRecord.optionFlag & query_flag_print_pgn) { + flag |= bslib::BoardCore::ParseMoveListFlag_create_san; + } + t->board->fromMoveList(gameID, moveText, bslib::Notation::san, flag, checkToStop); + } + + return true; +} + void Builder::queryGameData(SQLite::Database& db, int gameIdx) { auto ok = false; @@ -1291,8 +1350,9 @@ void Builder::parsePGNGame(int64_t gameID, const std::string& fenText, } -void Builder::searchPosition(SQLite::Database& db, const std::string& query) +void Builder::searchPosition(SQLite::Database* db, const std::vector& pgnPaths, const std::string& query) { + assert(paraRecord.task != Task::create); auto parser = new Parser; if (!parser->parse(query.c_str())) { std::cerr << "Error: " << parser->getErrorString() << std::endl; @@ -1303,10 +1363,10 @@ void Builder::searchPosition(SQLite::Database& db, const std::string& query) auto startTime = getNow(); // check if there at least a move fields (Moves, Moves1 or Moves2) - { + if (db) { searchField = SearchField::none; - SQLite::Statement stmt(db, "PRAGMA table_info(Games)"); + SQLite::Statement stmt(*db, "PRAGMA table_info(Games)"); while (stmt.executeStep()) { std::string fieldName = stmt.getColumn(1).getText(); @@ -1339,13 +1399,14 @@ void Builder::searchPosition(SQLite::Database& db, const std::string& query) if (parser->evaluate(bitboardVec)) { succCount++; - if ((query_flag & query_flag_print_all) || (succCount & 0xffff) == 0) { + if (paraRecord.optionFlag & query_flag_print_all) { std::cout << succCount << ". gameId: " << gameId; - if (query_flag & query_flag_print_fen) { + if (paraRecord.optionFlag & query_flag_print_fen) { std::cout << ", fen: " << board->getFen(); } - if (query_flag & query_flag_print_pgn) { - std::cout << ", pgn:\n " << board->toSimplePgn(); + if (paraRecord.optionFlag & query_flag_print_pgn) { + std::unordered_map tags; + std::cout << "\n\n" << board->toPgn(tags); } std::cout << std::endl; } @@ -1367,40 +1428,48 @@ void Builder::searchPosition(SQLite::Database& db, const std::string& query) << ", searchField: " << moveFieldName << std::endl; - succCount = 0; + succCount = 0; gameCnt = 0; - SQLite::Statement statement(db, "SELECT * FROM Games"); - int64_t cnt = 0; - for (; statement.executeStep(); cnt++) { - auto gameID = statement.getColumn("ID").getInt64(); - auto fenText = statement.getColumn("FEN").getText(); - - std::string moveText; - std::vector moveVec; - - if (searchField == SearchField::moves) { - moveText = statement.getColumn("Moves").getText(); - } else { - auto c = statement.getColumn(moveFieldName.c_str()); - auto moveBlob = static_cast(c.getBlob()); + if (db) { + SQLite::Statement statement(*db, "SELECT * FROM Games"); + for (; statement.executeStep(); gameCnt++) { + auto gameID = statement.getColumn("ID").getInt64(); + auto fenText = statement.getColumn("FEN").getText(); - if (!moveBlob) { - continue; + std::string moveText; + std::vector moveVec; + + if (searchField == SearchField::moves) { + moveText = statement.getColumn("Moves").getText(); + } else { + auto c = statement.getColumn(moveFieldName.c_str()); + auto moveBlob = static_cast(c.getBlob()); + + if (!moveBlob) { + continue; + } + auto sz = c.size(); + + for(auto i = 0; i < sz; ++i) { + moveVec.push_back(moveBlob[i]); + } } - auto sz = c.size(); - - for(auto i = 0; i < sz; ++i) { - moveVec.push_back(moveBlob[i]); + threadParsePGNGame(gameID, fenText, moveText, moveVec); + + if (succCount >= paraRecord.resultNumberLimit) { + break; } } - threadParsePGNGame(gameID, fenText, moveText, moveVec); + pool->wait_for_tasks(); - if (succCount && (query_flag & query_flag_stop_at_first_result)) { - break; + } else { + assert(!pgnPaths.empty()); + for(auto && path : pgnPaths) { + processPgnFile(path); } } - pool->wait_for_tasks(); + // Done, retrieve some last stats int64_t parsedGameCnt = 0, allHdpLen = 0; for(auto && t : threadMap) { parsedGameCnt += t.second.gameCnt; @@ -1411,6 +1480,7 @@ void Builder::searchPosition(SQLite::Database& db, const std::string& query) std::cout << std::endl << query << " DONE. Elapsed: " << elapsed << " ms, " << bslib::Funcs::secondToClockString(static_cast(elapsed / 1000), ":") + << ", total games: " << gameCnt << ", total results: " << succCount << ", time per results: " << elapsed / std::max(1, succCount) << " ms" << std::endl << std::endl << std::endl; @@ -1418,7 +1488,7 @@ void Builder::searchPosition(SQLite::Database& db, const std::string& query) delete parser; } -void Builder::bench(const std::string& dbPath, int cpu, const std::set