libsaria: Cache lowercase strings, too
This is useful for sorting the library when filling in the list, since I do many comparisons with the same artists and albums. This beats having to lowercase them every time!
This commit is contained in:
parent
8e4b3dfbfe
commit
a3130a7da5
|
@ -9,6 +9,7 @@ namespace libsaria
|
|||
{
|
||||
|
||||
set<string> *format_text(const string &);
|
||||
string *lowercase(const string &);
|
||||
void print_format_stats();
|
||||
|
||||
}
|
||||
|
|
|
@ -7,13 +7,19 @@
|
|||
using namespace std;
|
||||
|
||||
static map<string, set<string> > format_cache;
|
||||
static unsigned int hits;
|
||||
static map<string, string> lc_cache;
|
||||
static unsigned int format_hits;
|
||||
static unsigned int lc_hits;
|
||||
|
||||
set<string> *do_format(const string &text)
|
||||
void do_format(const string &text,
|
||||
map<string, set<string> >::iterator &words,
|
||||
map<string, string>::iterator &lc)
|
||||
{
|
||||
string word;
|
||||
string lc_string;
|
||||
set<string> word_set;
|
||||
pair< map<string, set<string> >::iterator, bool > ret;
|
||||
pair< map<string, set<string> >::iterator, bool > ret1;
|
||||
pair< map<string, string>::iterator, bool > ret2;
|
||||
char c, diff = 'a' - 'A';
|
||||
|
||||
for (unsigned int i = 0; i < text.size(); i++) {
|
||||
|
@ -42,8 +48,13 @@ set<string> *do_format(const string &text)
|
|||
case '+':
|
||||
case '"':
|
||||
case ' ':
|
||||
if (word != "")
|
||||
if (word != "") {
|
||||
word_set.insert(word);
|
||||
if (lc_string == "")
|
||||
lc_string = word;
|
||||
else
|
||||
lc_string += " " + word;
|
||||
}
|
||||
word = "";
|
||||
break;
|
||||
default:
|
||||
|
@ -52,11 +63,32 @@ set<string> *do_format(const string &text)
|
|||
}
|
||||
}
|
||||
|
||||
if (word != "")
|
||||
if (word != "") {
|
||||
word_set.insert(word);
|
||||
if (lc_string == "")
|
||||
lc_string = word;
|
||||
else
|
||||
lc_string += " " + word;
|
||||
}
|
||||
|
||||
ret = format_cache.insert( pair<string, set<string> >(text, word_set) );
|
||||
return &(ret.first->second);
|
||||
ret1 = format_cache.insert( pair<string, set<string> >(text, word_set) );
|
||||
ret2 = lc_cache.insert( pair<string, string>(text, lc_string) );
|
||||
words = ret1.first;
|
||||
lc = ret2.first;
|
||||
}
|
||||
|
||||
void find_unique_words(const string &text,
|
||||
map<string, set<string> >::iterator &words)
|
||||
{
|
||||
map<string, string>::iterator lc;
|
||||
do_format(text, words, lc);
|
||||
}
|
||||
|
||||
void find_lowercase(const string &text,
|
||||
map<string, string>::iterator &lc)
|
||||
{
|
||||
map<string, set<string> >::iterator words;
|
||||
do_format(text, words, lc);
|
||||
}
|
||||
|
||||
namespace libsaria
|
||||
|
@ -69,16 +101,29 @@ namespace libsaria
|
|||
|
||||
/* Not found in cache... */
|
||||
if (it == format_cache.end())
|
||||
return do_format(text);
|
||||
else {
|
||||
hits++;
|
||||
return &(it->second);
|
||||
}
|
||||
find_unique_words(text, it);
|
||||
else
|
||||
format_hits++;
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
string *lowercase(const string &text)
|
||||
{
|
||||
map<string, string>::iterator it;
|
||||
it = lc_cache.find(text);
|
||||
|
||||
/* Not found in cache */
|
||||
if (it == lc_cache.end())
|
||||
find_lowercase(text, it);
|
||||
else
|
||||
lc_hits++;
|
||||
return &(it->second);
|
||||
}
|
||||
|
||||
void print_format_stats()
|
||||
{
|
||||
println("Format cache hits: %u size: %u", hits, format_cache.size());
|
||||
println("Format cache hits: %u size: %u", format_hits, format_cache.size());
|
||||
println("Lowercase cache hits: %u size: %u", lc_hits, lc_cache.size());
|
||||
}
|
||||
|
||||
} /* Namespace: libsaria */
|
||||
|
|
|
@ -8,33 +8,12 @@ using namespace std;
|
|||
#include <libsaria/prefs.h>
|
||||
#include <libsaria/index.h>
|
||||
#include <libsaria/print.h>
|
||||
#include <libsaria/format.h>
|
||||
#include "library.h"
|
||||
|
||||
static list<libsaria::Track *> play_list;
|
||||
static list<libsaria::Track *>::iterator cur_track = play_list.end();
|
||||
|
||||
static string format(string s)
|
||||
{
|
||||
string res;
|
||||
char c, diff = 'a' - 'A';
|
||||
|
||||
/*
|
||||
* TODO: Break into words based on spaces and format each word
|
||||
* before joining. Turn numbers into their word form (3 -> three,
|
||||
* 20 -> twenty)
|
||||
*/
|
||||
for (unsigned int i = 0; i < s.size(); i++) {
|
||||
c = s[i];
|
||||
if ( (c >= 'a') && (c <= 'z') )
|
||||
res += c;
|
||||
else if ( (c >= 'A') && (c <= 'Z') )
|
||||
res += (c + diff);
|
||||
if ( (c >= '0') && (c <= '9') )
|
||||
res += c;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline bool compare_tracks(libsaria::Track *one, libsaria::Track *two)
|
||||
{
|
||||
return one->get_track() < two->get_track();
|
||||
|
@ -42,24 +21,24 @@ static inline bool compare_tracks(libsaria::Track *one, libsaria::Track *two)
|
|||
|
||||
static inline bool compare_albums(libsaria::Track *one, libsaria::Track *two)
|
||||
{
|
||||
string s_one = format(one->get_album());
|
||||
string s_two = format(two->get_album());
|
||||
if (s_one < s_two)
|
||||
string *s_one = libsaria::lowercase(one->get_album());
|
||||
string *s_two = libsaria::lowercase(two->get_album());
|
||||
if (*s_one < *s_two)
|
||||
return true;
|
||||
else if (s_one == s_two)
|
||||
else if (*s_one == *s_two)
|
||||
return compare_tracks(one, two);
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool compare_tracktags(libsaria::Track *one, libsaria::Track *two)
|
||||
{
|
||||
string s_one = format(one->get_artist());
|
||||
string s_two = format(two->get_artist());
|
||||
if (s_one == "")
|
||||
string *s_one = libsaria::lowercase(one->get_artist());
|
||||
string *s_two = libsaria::lowercase(two->get_artist());
|
||||
if (*s_one == "")
|
||||
return false;
|
||||
if ( (s_one < s_two) || (s_two == "") )
|
||||
if ( (*s_one < *s_two) || (*s_two == "") )
|
||||
return true;
|
||||
else if (s_one == s_two)
|
||||
else if (*s_one == *s_two)
|
||||
return compare_albums(one, two);
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue