Search optimizations

This commit is contained in:
2016-05-13 09:32:36 +02:00
parent 9c3c1585d5
commit 4ec7dc3ca5
7 changed files with 106 additions and 47 deletions

View File

@@ -26,6 +26,7 @@
#include <map>
#include <ostream>
#include <vector>
#include <set>
#include <string>
#pragma warning(push)
@@ -51,6 +52,12 @@ namespace ZRCola {
};
///
/// Blank character category
///
const chrcatid_t chrcatid_t_blank = {};
///
/// Compares two character category IDs
///
@@ -151,7 +158,32 @@ namespace ZRCola {
///
inline character_db() : idxChr(data) {}
void search_by_desc(_In_z_ const wchar_t *str, _Inout_ std::map<wchar_t, unsigned long> &hits, _Inout_ std::map<wchar_t, unsigned long> &hits_sub) const;
///
/// Search for characters by description in given categories
///
/// \param[in ] str Search string
/// \param[in ] cats Set of categories, character must be a part of
/// \param[inout] hits (character, count) map to append full-word hits to
/// \param[inout] hits_sub (character, count) map to append partial-word hits to
///
void Search(_In_z_ const wchar_t *str, _In_ const std::set<chrcatid_t> &cats, _Inout_ std::map<wchar_t, unsigned long> &hits, _Inout_ std::map<wchar_t, unsigned long> &hits_sub) const;
///
/// Get character category
///
/// \param[in] c Character
///
/// \returns
/// - Character category if character found
/// - `ZRCola::chrcatid_t_blank` otherwise
///
inline chrcatid_t GetCharCat(wchar_t c) const
{
char _chr[sizeof(character)];
((character *)_chr)->chr = c;
indexChar::size_type start;
return idxChr.find(*((character *)_chr), start) ? idxChr[start].cat : chrcatid_t_blank;
}
};

View File

@@ -248,6 +248,40 @@ namespace ZRCola {
return false;
}
///
/// Search for the first element in the index
///
/// \param[in] el Element we are looking for (needle)
/// \param[out] start Index of the first matching element found
///
/// \returns
/// - \c true if found
/// - \c false otherwise
///
bool find(_In_ const T_data &el, _Out_ size_type &start) const
{
// Start with the full search area.
size_t end;
for (start = 0, end = size(); start < end; ) {
size_type m = (start + end) / 2;
int r = compare(el, at(m));
if (r < 0) end = m;
else if (r > 0) start = m + 1;
else {
// Narrow the search area on the left to start at the first element in the run.
for (size_type end2 = m; start < end2;) {
size_type m = (start + end2) / 2;
int r = compare(el, at(m));
if (r <= 0) end2 = m; else start = m + 1;
}
return true;
}
}
return false;
}
private:
static int __cdecl compare_s(void *p, const void *a, const void *b)
{