Menu

[f613ec]: / src / scidbase.h  Maximize  Restore  History

Download this file

261 lines (232 with data), 7.9 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
/*
# Copyright (C) 2014 Fulvio Benini
* This file is part of Scid (Shane's Chess Information Database).
*
* Scid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation.
*
* Scid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Scid. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef SCIDBASE_H
#define SCIDBASE_H
#include "index.h"
#include "namebase.h"
#include "gfile.h"
#include "undoredo.h"
#include "game.h"
#include "tree.h"
#include "stored.h"
#include <vector>
struct scidBaseT {
struct Stats {
uint flagCount [IDX_NUM_FLAGS]; // Num of games with each flag set.
dateT minDate;
dateT maxDate;
uint64_t nYears;
uint64_t sumYears;
uint nResults [NUM_RESULT_TYPES];
uint nRatings;
uint64_t sumRatings;
uint minRating;
uint maxRating;
struct Eco {
uint count;
uint results [NUM_RESULT_TYPES];
};
Eco ecoCount0 [1];
Eco ecoCount1 [5];
Eco ecoCount2 [50];
Eco ecoCount3 [500];
Eco ecoCount4 [500*26];
};
struct TreeStat {
colorT toMove;
std::string SAN;
int resultW, resultD, resultB;
double exp;
int ngames, nexp;
TreeStat();
void add(int result, int eloW, int eloB) {
ngames++;
double r = 0;
switch (result) {
case RESULT_White: resultW++; r = 1; break;
case RESULT_Draw: resultD++; r = 0.5; break;
case RESULT_Black: resultB++; break;
default: return;
}
if (eloW == 0 || eloB == 0) return;
int eloDiff = eloB - eloW;
if (eloDiff < 800 && eloDiff >= -800) {
exp += r - expVect_[eloDiff+800];
nexp++;
}
}
bool operator<(const TreeStat& cmp) const { return ngames > cmp.ngames; }
private:
static double expVect_[1600];
};
scidBaseT() { Init(); }
~scidBaseT();
errorT Open (fileModeT mode = FMODE_Memory,
const char* filename = "",
bool create = true,
const Progress& progress = Progress());
errorT Close ();
std::string newFilter();
void deleteFilter(const char* filterName);
HFilter getFilter(const char* filterName);
const std::string& getFileName() const { return fileName_; }
bool isReadOnly() const { return (fileMode==FMODE_ReadOnly); }
gamenumT numGames() const { return idx->GetNumGames(); }
errorT getExtraInfo(const std::string& tagname, std::string* res) const;
errorT setExtraInfo(const std::string& tagname, const char* new_value);
const IndexEntry* getIndexEntry(gamenumT g) const {
return idx->GetEntry(g);
}
const NameBase* getNameBase() const {
return nb;
}
FastGame getGame(const IndexEntry* ie) const {
return gfile->ReadGame(ie->GetOffset(), ie->GetLength());
}
errorT getGame(const IndexEntry* ie, ByteBuffer* bb) const {
return gfile->ReadGame(bb, ie->GetOffset(), ie->GetLength());
}
errorT addGames(scidBaseT* sourceBase, const HFilter& filter, const Progress& progress);
errorT addGame(scidBaseT* sourceBase, uint gNum);
errorT saveGame(Game* game, bool clearCache, gamenumT idx = IDX_NOT_FOUND);
bool getFlag(uint flag, uint gNum) const {
return idx->GetEntry(gNum)->GetFlag (flag);
}
errorT setFlag(bool value, uint flag, uint gNum){
ASSERT(gNum < idx->GetNumGames());
IndexEntry* ie = idx->FetchEntry (gNum);
ie->SetFlag (flag, value);
errorT res = idx->WriteEntry (ie, gNum, false);
validStats_ = false;
// TODO: necessary only for sortcaches with SORTING_deleted (and SORTING_flags when implemented)
// idx->IndexUpdated(gNum);
return res;
}
errorT setFlag(bool value, uint flag, const HFilter& filter) {
errorT res = OK;
for (gamenumT gNum = 0, n = numGames(); gNum < n; gNum++) {
if (*filter && filter.get(gNum) == 0) continue;
res = setFlag(value, flag, gNum);
if (res != OK) return res;
}
return res;
}
errorT invertFlag(uint flag, uint gNum) {
return setFlag(! getFlag(flag, gNum), flag, gNum);
}
errorT invertFlag(uint flag, const HFilter& filter) {
errorT res = OK;
for (gamenumT i = 0, n = numGames(); i < n; i++) {
if (*filter && filter.get(i) == 0) continue;
res = invertFlag(flag, i);
if (res != OK) return res;
}
return res;
}
const Stats* getStats() const;
std::vector<scidBaseT::TreeStat> getTreeStat(const HFilter& filter);
uint getNameFreq (nameT nt, idNumberT id) {
if (nameFreq_[nt].size() == 0) calcNameFreq();
return nameFreq_[nt][id];
}
errorT getCompactStat(uint* n_deleted,
uint* n_unused,
uint* n_sparse,
uint* n_badNameId);
errorT compact(const Progress& progress);
SortCache* CreateSortCache(const char* criteria) const {
return idx->CreateSortCache(nb, criteria);
}
void FreeSortCache(const char* criteria) const {
return idx->FreeSortCache(criteria);
}
errorT GetRange(const char *criteria, uint idx, uint count, const HFilter& filter, uint *result) const {
return this->idx->GetRange(nb, criteria, idx, count, filter, result);
}
uint GetRangeLocation(const char *criteria, const HFilter& filter, uint gnumber) const {
return idx->GetRangeLocation(nb, criteria, filter, gnumber);
}
uint GetRangeLocation(const char *criteria, const HFilter& filter, const char* text, uint start, bool forward) const {
return idx->GetRangeLocation(nb, criteria, filter, text, start, forward);
}
void setDuplicates(uint* duplicates) {
if (duplicates_ != NULL) { delete[] duplicates_; duplicates_ = NULL; }
duplicates_ = duplicates;
}
uint getDuplicates(gamenumT gNum) {
return (duplicates_ == NULL) ? 0 : duplicates_[gNum];
}
//TODO: private:
/* clearCaches:
After changing one or more games this function MUST be called
(to update all the caches and write the namebase file and index header)
- gNum: id of the game changed (IDX_NOT_FOUND update all the games)
*/
errorT clearCaches(gamenumT gNum = IDX_NOT_FOUND, bool writeFiles = true);
Index* idx; // the Index file in memory for this base.
NameBase* nb; // the NameBase file in memory.
bool inUse; // true if the database is open (in use).
treeT tree;
TreeCache treeCache;
ByteBuffer* bbuf;
TextBuffer* tbuf;
Filter* dbFilter;
Filter* treeFilter;
//TODO: this vars do not belong to scidBaseT class
Game* game; // the active game for this base.
int gameNumber; // game number of active game.
bool gameAltered; // true if game is modified
UndoRedo<Game, 30> gameAlterations;
private:
GFile* gfile;
std::string fileName_; // File name without ".si" suffix
fileModeT fileMode; // Read-only, write-only, or both.
std::vector< std::pair<std::string, Filter*> > filters_;
mutable bool validStats_;
mutable Stats* stats_;
std::vector <int> nameFreq_ [NUM_NAME_TYPES];
uint* duplicates_; // For each game: idx of duplicate game + 1 (0 if there is no duplicate).
scidBaseT(const scidBaseT&);
scidBaseT& operator=(const scidBaseT&);
void Init();
void clear();
errorT addGameHelper(scidBaseT* sourceBase, uint gNum);
errorT saveGameHelper(IndexEntry* iE, ByteBuffer* bbuf, gamenumT oldIdx = IDX_NOT_FOUND);
void calcNameFreq ();
Filter* fetchFilter(uint idx) {
if (idx == 0) return dbFilter;
if (idx == 1) return treeFilter;
idx -= 2;
if (idx >= filters_.size()) return 0;
return filters_[idx].second;
}
Filter* fetchFilter(const std::string& name) {
Filter* res = 0;
if (name == "dbfilter") res = dbFilter;
else if (name == "tree") res = treeFilter;
else {
for (uint i=0; i < filters_.size(); i++) {
if (filters_[i].first == name) {
res = filters_[i].second;
break;
}
}
}
return res;
}
};
#endif