71 scid::core::uint changedRatings = 0;
72 scid::core::uint changedGames = 0;
76 scid::core::uint flagCount[IndexEntry::IDX_NUM_FLAGS];
78 scid::core::dateT minDate;
79 scid::core::dateT maxDate;
82 scid::core::uint nResults[scid::core::NUM_RESULT_TYPES];
83 scid::core::uint nRatings;
85 scid::core::uint minRating;
86 scid::core::uint maxRating;
91 scid::core::uint count;
92 scid::core::uint results[scid::core::NUM_RESULT_TYPES];
96 const Eco* getEcoStats(
const char* ecoStr)
const;
101 Eco ecoStats_[(1 + (1 << 16) / 131) * 27];
102 Eco ecoGroup1_[(1 + (1 << 16) / 131) / 100];
103 Eco ecoGroup2_[(1 + (1 << 16) / 131) / 10];
104 Eco ecoGroup3_[(1 + (1 << 16) / 131)];
110 scid::core::errorT open(std::string_view dbType, fileModeT fMode,
const char* filename,
115 std::string getFileName()
const;
116 bool isOpen()
const {
return inUse; }
117 bool isReadOnly()
const {
return fileMode_ == FMODE_ReadOnly; }
118 gamenumT numGames()
const {
return idx->
GetNumGames(); }
125 scid::core::errorT
setExtraInfo(
const char* tagname,
const char* new_value);
127 const IndexEntry* getIndexEntry(gamenumT g)
const {
128 assert(g < numGames());
129 return idx->GetEntry(g);
131 const IndexEntry* getIndexEntry_bounds(gamenumT g)
const {
132 static_assert(std::is_unsigned_v<gamenumT>);
133 return g < numGames() ? getIndexEntry(g) : nullptr;
135 GameInfo gameInfo(gamenumT g)
const;
136 std::optional<GameInfo> gameInfoBounds(gamenumT g)
const {
137 static_assert(std::is_unsigned_v<gamenumT>);
138 return g < numGames() ? std::optional<GameInfo>{gameInfo(g)}
141 scid::core::errorT updateGameInfo(gamenumT g,
const GameInfoUpdate& update);
142 TagRoster tagRoster(gamenumT gnum)
const {
143 return tagRoster(*getIndexEntry(gnum));
145 TagRoster tagRoster(IndexEntry
const& ie)
const {
146 return TagRoster::make(ie, *nb_);
149 const NameBase* getNameBase()
const {
return nb_; }
152 scid::core::ratingT
peakElo(idNumberT playerID)
const {
153 if (peakEloCache_.empty()) {
154 for (gamenumT gnum = 0, n = numGames(); gnum < n; gnum++) {
156 auto updateMax = [&](
auto id,
auto elo) {
157 auto& max_value = peakEloCache_[id];
158 max_value = std::max(max_value, elo);
160 updateMax(ie.GetWhite(), ie.GetWhiteElo());
161 updateMax(ie.GetBlack(), ie.GetBlackElo());
164 return peakEloCache_[playerID];
168 char* scidFlags, std::size_t scidFlagsLen)
const;
170 char* scidFlags, std::size_t scidFlagsLen)
const;
171 scid::core::errorT loadGameMovesOnly(gamenumT gNum,
173 scid::core::errorT loadGameMovesOnly(
const IndexEntry& ie,
175 scid::core::errorT gameTags(
177 std::vector<std::pair<std::string, std::string>>& dest)
const;
178 scid::core::errorT loadStandardTags(gamenumT gNum,
181 std::size_t scidFlagsLen)
const;
182 scid::core::errorT gameTags(
184 std::vector<std::pair<std::string, std::string>>& dest)
const;
185 std::vector<scid::core::FullMove> mainlineMoves(
186 gamenumT gNum, std::size_t maxPly)
const;
187 std::vector<scid::core::FullMove> mainlineMoves(
188 const IndexEntry* ie, std::size_t maxPly)
const;
189 std::string moveSAN(gamenumT gNum,
int plyToSkip,
int count)
const;
190 std::string moveSAN(
const IndexEntry* ie,
int plyToSkip,
int count)
const;
191 std::pair<scid::core::errorT, size_t>
193 scid::core::dateT oldDate, scid::core::dateT newDate);
194 std::pair<scid::core::errorT, size_t>
196 scid::core::dateT oldDate,
197 scid::core::dateT newDate);
198 std::pair<scid::core::errorT, size_t>
199 setPlayerRatings(
HFilter filter,
const Progress& progress, idNumberT player,
200 scid::core::ratingT rating,
201 scid::core::ratingTypeT ratingType);
202 template <
typename TRatingResolver>
203 std::pair<scid::core::errorT, RatingUpdateStats> updatePlayerRatings(
205 bool saveRatings, TRatingResolver ratingFor);
206 scid::core::errorT searchBoard(
const IndexEntry& ie,
212 bool possibleFlippedMatch,
213 gameExactMatchT searchType,
214 scid::core::uint& ply)
const;
215 scid::core::errorT searchBoard(gamenumT gNum,
221 bool possibleFlippedMatch,
222 gameExactMatchT searchType,
223 scid::core::uint& ply)
const;
224 bool materialSearchMatch(
const IndexEntry& ie,
bool possibleMatch,
225 bool possibleFlippedMatch,
226 scid::core::byte* min, scid::core::byte* max,
227 scid::core::byte* minFlipped,
228 scid::core::byte* maxFlipped,
229 patternT* patterns, std::size_t patternCount,
231 std::size_t flippedPatternCount,
int minPly,
232 int maxPly,
int matchLength,
bool oppBishops,
233 bool sameBishops,
int minDiff,
235 bool materialSearchMatch(gamenumT gNum,
bool possibleMatch,
236 bool possibleFlippedMatch,
237 scid::core::byte* min, scid::core::byte* max,
238 scid::core::byte* minFlipped,
239 scid::core::byte* maxFlipped,
240 patternT* patterns, std::size_t patternCount,
242 std::size_t flippedPatternCount,
int minPly,
243 int maxPly,
int matchLength,
bool oppBishops,
244 bool sameBishops,
int minDiff,
250 scid::core::errorT importGames(
const scidBaseT* srcBase,
const HFilter& filter,
252 scid::core::errorT importGames(std::string_view dbType,
const char* filename,
253 const Progress& progress, std::string& errorMsg);
264 gamenumT replacedGameId = INVALID_GAMEID);
265 scid::core::errorT addGame(
scid::core::Game const& game,
const char* scidFlags) {
266 return saveGame(game, scidFlags, INVALID_GAMEID);
269 bool getFlag(scid::core::uint flag, scid::core::uint gNum)
const {
270 return idx->GetEntry(gNum)->GetFlag(flag);
272 scid::core::errorT setFlag(
bool value, scid::core::uint flag, scid::core::uint gNum);
273 scid::core::errorT setFlags(
bool value, scid::core::uint flag,
const HFilter& filter);
274 scid::core::errorT invertFlag(scid::core::uint flag, scid::core::uint gNum);
275 scid::core::errorT invertFlags(scid::core::uint flag,
const HFilter& filter);
283 void deleteFilter(
const char* filterId);
284 HFilter getFilter(std::string_view filterId)
const;
286 gamenumT defaultFilterCount()
const {
return dbFilter->
Count(); }
287 scid::core::byte defaultFilterGet(gamenumT g)
const {
return dbFilter->
Get(g); }
288 void defaultFilterSet(gamenumT g, scid::core::byte value) { dbFilter->
Set(g, value); }
289 void defaultFilterFill(scid::core::byte value) { dbFilter->
Fill(value); }
290 uint64_t cacheInvalidationToken()
const {
return cacheInvalidationToken_; }
300 std::string_view maskFilter)
const;
305 std::pair<std::string, std::string>
308 const Stats& getStats()
const;
309 std::vector<TreeNode> getTreeStat(
const HFilter& filter)
const;
310 scid::core::uint getNameFreq(nameT nt, idNumberT
id) {
311 if (nameFreq_[nt].size() == 0)
313 return nameFreq_[nt][id];
316 scid::core::errorT getCompactStat(
unsigned long long* n_deleted,
317 unsigned long long* n_unused,
318 unsigned long long* n_sparse,
319 unsigned long long* n_badNameId);
320 scid::core::errorT compact(
const Progress& progress);
358 size_t listGames(
const char* criteria,
size_t start,
size_t count,
359 const HFilter& filter, gamenumT* destCont);
392 template <
typename TInitFunc,
typename TMapFunc>
393 std::pair<scid::core::errorT, size_t>
395 const std::vector<std::string>& newNames, TInitFunc fnInit,
406 std::pair<scid::core::errorT, size_t>
408 std::vector<std::string_view>
const& removeTags);
410 std::unique_ptr<gamenumT[]> extractDuplicates() {
411 return std::move(duplicates_);
413 void setDuplicates(std::unique_ptr<gamenumT[]> duplicates) {
414 duplicates_ = std::move(duplicates);
416 gamenumT getDuplicates(gamenumT gNum)
const {
417 return duplicates_ ? duplicates_[gNum] : 0;
425 std::unique_ptr<Storage> storage_;
429 std::vector<std::pair<std::string, Filter*>> filters_;
430 mutable Filter all_filter_{0};
431 mutable Stats* stats_;
432 std::array<std::vector<int>, NUM_NAME_TYPES> nameFreq_;
434 std::unique_ptr<gamenumT[]> duplicates_;
435 std::vector<std::pair<std::string, SortCache*>> sortCaches_;
436 mutable std::unordered_map<idNumberT, scid::core::ratingT> peakEloCache_;
437 scid::core::errorT err_open_ = scid::core::OK;
438 uint64_t cacheInvalidationToken_ = 0;
441 friend class SearchPos;
443 static GameInfo makeGameInfo_(
const IndexEntry& ie);
444 ByteBuffer gameData(
const IndexEntry& ie)
const;
445 GameView gameView(
const IndexEntry* ie)
const;
446 scid::core::errorT openHelper(std::string_view dbType, fileModeT mode,
447 const char* filename,
const Progress& progress = {});
454 scid::core::errorT beginTransaction();
461 scid::core::errorT endTransaction(gamenumT gameId = INVALID_GAMEID);
463 scid::core::errorT importGameHelper(
const scidBaseT* sourceBase, scid::core::uint gNum);
464 scid::core::errorT saveGameData(IndexEntry
const& ie, TagRoster
const& tags,
465 ByteBuffer
const& data, gamenumT replaced);
466 scid::core::errorT saveIndexEntry(IndexEntry
const& ie, gamenumT replaced);
467 std::pair<scid::core::errorT, idNumberT> addName(nameT nt,
const char* name);
469 SortCache* getSortCache(
const char* criteria);
471 template <
typename TOper>
472 std::pair<scid::core::errorT, size_t>
473 transformIndex(HFilter hfilter,
const Progress& progress, TOper entry_op) {
474 if (
auto errModify = beginTransaction())
475 return {errModify, 0};
477 auto res = transformIndex_(hfilter, progress, entry_op);
478 auto err = endTransaction();
479 res.first = (res.first == scid::core::OK) ? err : res.first;
493 template <
typename TOper>
494 std::pair<scid::core::errorT, size_t>
495 transformIndex_(HFilter hfilter,
const Progress& progress, TOper entry_op) {
496 size_t nCorrections = 0;
498 size_t totProg = hfilter->size();
499 for (
auto& gnum : hfilter) {
500 if ((++iProg % 8192 == 0) && !progress.report(iProg, totProg))
501 return std::make_pair(scid::core::ERROR_UserCancel, nCorrections);
503 IndexEntry newIE = *getIndexEntry(gnum);
504 if (!entry_op(newIE))
507 auto err = saveIndexEntry(newIE, gnum);
508 if (err != scid::core::OK)
509 return std::make_pair(err, nCorrections);
513 return std::make_pair(scid::core::OK, nCorrections);