19#ifndef SCID_NAMEBASE_H
20#define SCID_NAMEBASE_H
22#include "scid/database/game_id.h"
23#include "scid/database/index.h"
24#include "scid/database/indexentry.h"
25#include "scid/database/misc.h"
36using nameT = unsigned;
51 std::vector<std::unique_ptr<const char[]>> names_[NUM_NAME_TYPES];
53 bool operator()(
const char* str1,
const char* str2)
const {
66 return strCompare(str1, str2) < 0;
68 return static_cast<uint32_t
>(*str1) <
static_cast<uint32_t
>(*str2);
71 std::map<const char*, idNumberT, idxCmp> idx_[NUM_NAME_TYPES];
78 idNumberT namebase_add(
79 nameT nt, std::string_view name,
80 std::map<const char*, idNumberT, idxCmp>::iterator* hint =
nullptr) {
82 ASSERT(names_[nt].size() <= std::numeric_limits<idNumberT>::max());
84 char* alloc =
new char[name.size() + 1];
85 std::copy_n(name.data(), name.size(), alloc);
86 alloc[name.size()] =
'\0';
87 idNumberT newID =
static_cast<idNumberT
>(names_[nt].size());
88 names_[nt].emplace_back(alloc);
90 idx_[nt].emplace_hint(*hint, alloc, newID);
92 idx_[nt].emplace(alloc, newID);
100 idNumberT namebase_find_or_add(nameT nt,
const char* name) {
104 auto it = nb.lower_bound(name);
105 if (it != nb.end() && !nb.key_comp()(name, it->first))
108 return namebase_add(nt, name, &it);
113 size_t namebase_size(nameT nt)
const {
116 return names_[nt].size();
125 bool insert(
const char* name,
size_t nameLen, nameT nt, idNumberT
id) {
126 if (
id >= names_[nt].size())
127 names_[nt].resize(
id +
size_t{1});
132 char* buf =
new char[nameLen + 1];
133 std::copy_n(name, nameLen, buf);
135 names_[nt][id].reset(buf);
136 auto it = idx_[nt].emplace_hint(idx_[nt].end(), buf,
id);
137 return it->second == id;
153 size_t maxMatches)
const {
156 std::vector<idNumberT> res;
157 size_t len = strlen(str);
158 for (
auto it = idx_[nt].lower_bound(str);
159 it != idx_[nt].end() && res.size() < maxMatches; ++it) {
160 const char* s = it->first;
161 if (strlen(s) < len || !std::equal(str, str + len, s))
163 res.emplace_back(it->second);
174 const char*
GetName(nameT nt, idNumberT
id)
const {
176 return names_[nt][id].get();
183 const decltype(idx_)&
getNames()
const {
return idx_; }
192 return static_cast<idNumberT
>(names_[nt].size());
202 scid::core::errorT
FindExactName(nameT nt,
const char* str, idNumberT* idPtr)
const {
205 auto it = idx_[nt].find(str);
206 if (it != idx_[nt].end()) {
207 *idPtr = (*it).second;
208 return scid::core::OK;
210 return scid::core::ERROR_NameNotFound;
219 std::vector<uint32_t> res(names_[nt].size());
221 names_[nt].begin(), names_[nt].end(), res.begin(),
222 [](
auto const& name) { return strStartHash(name.get()); });
230 std::array<std::vector<int>, NUM_NAME_TYPES>
232 std::array<std::vector<int>, NUM_NAME_TYPES> resVec;
233 for (nameT n = NAME_PLAYER; n < NUM_NAME_TYPES; n++) {
236 for (gamenumT i = 0, n = idx.
GetNumGames(); i < n; i++) {
238 resVec[NAME_PLAYER][ie->GetWhite()] += 1;
239 resVec[NAME_PLAYER][ie->GetBlack()] += 1;
240 resVec[NAME_EVENT][ie->GetEvent()] += 1;
241 resVec[NAME_SITE][ie->GetSite()] += 1;
242 resVec[NAME_ROUND][ie->GetRound()] += 1;
252 size_t n_invalid = 0;
253 std::array<size_t, NUM_NAME_TYPES> maxID;
254 for (
auto n = nameT{}; n < NUM_NAME_TYPES; n++) {
257 for (gamenumT i = 0, n = idx.
GetNumGames(); i < n; i++) {
259 n_invalid += ie->GetWhite() < maxID[NAME_PLAYER] ? 0 : 1;
260 n_invalid += ie->GetBlack() < maxID[NAME_PLAYER] ? 0 : 1;
261 n_invalid += ie->GetEvent() < maxID[NAME_EVENT] ? 0 : 1;
262 n_invalid += ie->GetSite() < maxID[NAME_SITE] ? 0 : 1;
263 n_invalid += ie->GetRound() < maxID[NAME_ROUND] ? 0 : 1;
285 if (strIsAlphaPrefix(str,
"player"))
287 if (strIsAlphaPrefix(str,
"event"))
289 if (strIsAlphaPrefix(str,
"site"))
291 if (strIsAlphaPrefix(str,
"round"))
293 if (strIsAlphaPrefix(
"player", str))
295 if (strIsAlphaPrefix(
"event", str))
297 if (strIsAlphaPrefix(
"site", str))
299 if (strIsAlphaPrefix(
"round", str))
315 template <
typename TEntry>
318 res.event = nb.
GetName(NAME_EVENT, ie.GetEvent());
319 res.site = nb.
GetName(NAME_SITE, ie.GetSite());
320 res.white = nb.
GetName(NAME_PLAYER, ie.GetWhite());
321 res.black = nb.
GetName(NAME_PLAYER, ie.GetBlack());
322 res.round = nb.
GetName(NAME_ROUND, ie.GetRound());
326 template <
typename TEntry,
typename Fn>
327 auto map(TEntry& dest, Fn getID)
const {
329 auto [err, id] = getID(NAME_EVENT, event);
335 auto [err, id] = getID(NAME_SITE, site);
341 auto [err, id] = getID(NAME_ROUND, round);
347 auto [err, id] = getID(NAME_PLAYER, white);
353 auto [err, id] = getID(NAME_PLAYER, black);
Definition indexentry.h:51
gamenumT GetNumGames() const
Header getter functions.
This class stores the database's names (players, events, sites and rounds).
Definition namebase.h:50
const char * GetName(nameT nt, idNumberT id) const
Retrieve a name.
Definition namebase.h:174
const decltype(idx_) & getNames() const
Definition namebase.h:183
std::array< std::vector< int >, NUM_NAME_TYPES > calcNameFreq(Index const &idx) const
Counts how many times each name is used.
Definition namebase.h:231
idNumberT GetNumNames(nameT nt) const
Definition namebase.h:190
std::vector< idNumberT > getFirstMatches(nameT nt, const char *str, size_t maxMatches) const
Get the first few matches of a name prefix.
Definition namebase.h:152
size_t count_invalid_ids(Index const &idx) const
Counts how many invalid IDs (references to names that do not exist in this NameBase) are present in i...
Definition namebase.h:251
bool insert(const char *name, size_t nameLen, nameT nt, idNumberT id)
DEPRECATED Add a name (string) and its associated id to the NameBase.
Definition namebase.h:125
scid::core::errorT FindExactName(nameT nt, const char *str, idNumberT *idPtr) const
Finds an exact full, case-sensitive name.
Definition namebase.h:202
std::vector< uint32_t > generateHashMap(nameT nt) const
For every name generates a 32bit hash with the first 4 chars.
Definition namebase.h:218
static nameT NameTypeFromString(const char *str)
Match a string to a nameT.
Definition namebase.h:282
void Clear()
Frees memory, leaving the object empty.
Definition namebase.h:143
static bool IsValidNameType(nameT nt)
Validate a nameT type.
Definition namebase.h:273
class StrRange - parse a string interpreting its content as 1 or 2 integers separated by whitespace.
Definition common.h:30
The Seven Tag Roster defined in the PGN standard is stored in the IndexEntry, but 5 are indexes that ...
Definition namebase.h:308