Speed up mood loading.
authorAndre Noll <maan@systemlinux.org>
Sat, 29 Sep 2007 11:13:50 +0000 (13:13 +0200)
committerAndre Noll <maan@systemlinux.org>
Sat, 29 Sep 2007 11:13:50 +0000 (13:13 +0200)
The old code passed a pointer to the row of the audio file table to the
mood scoring functions. The scoring functions had to obtain the afsi,
afhi, path from that row pointer. Thus, at mood load time, the afsi,
afhi, path was extracted N times for each audio file if there are N
mood lines that used this info.

This patch changes the mood scoring functions so that they take
three pointers to afsi, afhi, path instead of the row pointer.
add_item_score(), the single caller of the mood scoring functions,
provides these pointers, i.e. they get extracted from the row pointer
only once per audio file.

This is still not optimal as most scoring functions use only one of
the three pointers. But let's not over-engineer the thing.

afs.h
aft.c
mood.c

diff --git a/afs.h b/afs.h
index 72081ab6163fbc7748a1332e4e1701cde8433184..8b86cace31ee0742f2f586d31acfcd8822ae5886 100644 (file)
--- a/afs.h
+++ b/afs.h
@@ -104,6 +104,7 @@ int open_and_update_audio_file(struct osl_row *aft_row, struct audio_file_data *
 int load_afsi(struct afs_info *afsi, struct osl_object *obj);
 void save_afsi(struct afs_info *afsi, struct osl_object *obj);
 int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi);
 int load_afsi(struct afs_info *afsi, struct osl_object *obj);
 void save_afsi(struct afs_info *afsi, struct osl_object *obj);
 int get_afsi_of_row(const struct osl_row *row, struct afs_info *afsi);
+int get_afhi_of_row(const struct osl_row *row, struct audio_format_info *afhi);
 int get_audio_file_path_of_row(const struct osl_row *row, char **path);
 int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj);
 int audio_file_loop(void *private_data, osl_rbtree_loop_func *func);
 int get_audio_file_path_of_row(const struct osl_row *row, char **path);
 int get_afsi_object_of_row(const struct osl_row *row, struct osl_object *obj);
 int audio_file_loop(void *private_data, osl_rbtree_loop_func *func);
diff --git a/aft.c b/aft.c
index bcceb4b0b7911707f88644c6f505189db2189934..c5effc66e68cce996dc99260b7f8da843a985532 100644 (file)
--- a/aft.c
+++ b/aft.c
@@ -592,7 +592,7 @@ static int get_hash_of_row(const struct osl_row *row, HASH_TYPE **hash)
  *
  * \sa get_chunk_table_of_row().
  */
  *
  * \sa get_chunk_table_of_row().
  */
-static int get_afhi_of_row(const struct osl_row *row, struct audio_format_info *afhi)
+int get_afhi_of_row(const struct osl_row *row, struct audio_format_info *afhi)
 {
        struct osl_object obj;
        int ret = osl_get_object(audio_file_table, row, AFTCOL_AFHI,
 {
        struct osl_object obj;
        int ret = osl_get_object(audio_file_table, row, AFTCOL_AFHI,
diff --git a/mood.c b/mood.c
index 56ee1c43b5af30b6da5766e8c1c23ff2a67f40bb..e685fd91c982fd82cd9afa69c3a06932328907a5 100644 (file)
--- a/mood.c
+++ b/mood.c
@@ -47,7 +47,8 @@ struct afs_statistics statistics;
  *
  * \sa struct mood_method, mood_parser.
  */
  *
  * \sa struct mood_method, mood_parser.
  */
-typedef int mood_score_function(const struct osl_row*, void *);
+typedef int mood_score_function(const char *path, const struct afs_info *afsi,
+               const struct audio_format_info *afhi, const void *data);
 
 /**
  * Pre-process a mood line.
 
 /**
  * Pre-process a mood line.
@@ -163,19 +164,17 @@ static uint64_t int_sqrt(uint64_t x)
        return res;
 }
 
        return res;
 }
 
-static int mm_played_rarely_score_function(const struct osl_row *row,
-       __a_unused void *ignored)
+static int mm_played_rarely_score_function(__a_unused const char *path,
+               const struct afs_info *afsi,
+               __a_unused const struct audio_format_info *afhi,
+               __a_unused const void *data)
 {
 {
-       struct afs_info afsi;
        unsigned num;
        unsigned num;
-       int ret = get_afsi_of_row(row, &afsi);
+       int ret = get_num_admissible_files(&num);
 
        if (ret < 0)
                return 0;
 
        if (ret < 0)
                return 0;
-       ret = get_num_admissible_files(&num);
-       if (ret < 0)
-               return 0;
-       if (statistics.num_played_sum - num * afsi.num_played
+       if (statistics.num_played_sum - num * afsi->num_played
                        > int_sqrt(statistics.num_played_qd * num))
                return 100;
        return -100;
                        > int_sqrt(statistics.num_played_qd * num))
                return 100;
        return -100;
@@ -188,15 +187,14 @@ static int mm_played_rarely_parser(const char *arg, __a_unused void **ignored)
        return 1;
 }
 
        return 1;
 }
 
-static int mm_name_like_score_function(const struct osl_row *row, void *data)
+static int mm_name_like_score_function(const char *path,
+               __a_unused const struct afs_info *afsi,
+               __a_unused const struct audio_format_info *afhi,
+               const void *data)
 {
 {
-       char *path;
-       int ret = get_audio_file_path_of_row(row, &path);
-
-       if (ret < 0)
-               return 0;
-       ret = fnmatch(data, path, 0);
-       return ret? -100 : 100;
+       if (fnmatch(data, path, 0))
+               return -100;
+       return 100;
 }
 
 static int mm_name_like_parser(const char *arg, void **data)
 }
 
 static int mm_name_like_parser(const char *arg, void **data)
@@ -222,28 +220,40 @@ static int mm_is_set_parser(const char *arg, void **bitnum)
        return ret;
 }
 
        return ret;
 }
 
-static int mm_is_set_score_function(const struct osl_row *row, void *bitnum)
+static int mm_is_set_score_function(__a_unused const char *path,
+               __a_unused const struct afs_info *afsi,
+               __a_unused const struct audio_format_info *afhi,
+               const void *data)
 {
 {
-       unsigned char *bn = bitnum;
-       struct afs_info afsi;
-       int ret = get_afsi_of_row(row, &afsi);
-
-       if (ret < 0)
-               return 0;
-       if (afsi.attributes & (1ULL << *bn))
+       const unsigned char *bn = data;
+       if (afsi->attributes & (1ULL << *bn))
                return 100;
        return -100;
 }
 
                return 100;
        return -100;
 }
 
-/* returns 1 if row matches score item, -1 otherwise */
+/* returns 1 if row matches score item, negative otherwise */
 static int add_item_score(const struct osl_row *row, struct mood_item *item, long *score,
                long *score_arg_sum)
 {
 static int add_item_score(const struct osl_row *row, struct mood_item *item, long *score,
                long *score_arg_sum)
 {
-       int ret = 100;
+       struct afs_info afsi;
+       struct audio_format_info afhi;
+       char *path;
+       int ret;
 
        *score_arg_sum += item->random_score? 100 : PARA_ABS(item->score_arg);
 
        *score_arg_sum += item->random_score? 100 : PARA_ABS(item->score_arg);
+       ret = 100;
        if (item->method) {
        if (item->method) {
-               ret = item->method->score_function(row, item->parser_data);
+               ret = get_afsi_of_row(row, &afsi);
+               if (ret< 0)
+                       return ret;
+               ret = get_afhi_of_row(row, &afhi);
+               if (ret< 0)
+                       return ret;
+               ret = get_audio_file_path_of_row(row, &path);
+               if (ret< 0)
+                       return ret;
+               ret = item->method->score_function(path, &afsi, &afhi,
+                       item->parser_data);
                if ((ret < 0 && !item->logical_not) || (ret >= 0 && item->logical_not))
                        return -1; /* no match */
        }
                if ((ret < 0 && !item->logical_not) || (ret >= 0 && item->logical_not))
                        return -1; /* no match */
        }
@@ -270,8 +280,6 @@ static int compute_mood_score(const struct osl_row *aft_row, struct mood *m,
        list_for_each_entry(item, &m->accept_list, mood_item_node)
                if (add_item_score(aft_row, item, &score, &score_arg_sum) > 0)
                        match = 1;
        list_for_each_entry(item, &m->accept_list, mood_item_node)
                if (add_item_score(aft_row, item, &score, &score_arg_sum) > 0)
                        match = 1;
-       if (list_empty(&m->accept_list))
-               PARA_NOTICE_LOG("accrpt list empty\n");
        /* reject if there is no matching entry in the accept list */
        if (!match && !list_empty(&m->accept_list))
                return -E_NOT_ADMISSIBLE;
        /* reject if there is no matching entry in the accept list */
        if (!match && !list_empty(&m->accept_list))
                return -E_NOT_ADMISSIBLE;