]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - score.c
Merge topic branch t/sf_float into pu
[paraslash.git] / score.c
diff --git a/score.c b/score.c
index fa12663cb936535cd43d623c37b331a86896a1cb..c03e3472da306a1d535b201ea2d23c90ccf8f90a 100644 (file)
--- a/score.c
+++ b/score.c
@@ -77,10 +77,10 @@ static struct osl_table_description score_table_desc = {
 };
 
 /* On errors (negative return value) the content of score is undefined. */
-static int get_score_of_row(void *score_row, long *score)
+static int get_score_of_row(struct osl_table *t, void *score_row, long *score)
 {
        struct osl_object obj;
-       int ret = osl(osl_get_object(score_table, score_row, SCORECOL_SCORE, &obj));
+       int ret = osl(osl_get_object(t, score_row, SCORECOL_SCORE, &obj));
 
        if (ret >= 0)
                *score = *(long *)obj.data;
@@ -88,14 +88,15 @@ static int get_score_of_row(void *score_row, long *score)
 }
 
 /**
- * Add an entry to the table of admissible files.
+ * Add a (row, score) pair to the score table.
  *
- * \param aft_row The audio file to be added.
- * \param score The score for this file.
+ * \param aft_row Identifies the audio file to be added.
+ * \param score The score value of the audio file.
+ * \param t NULL means to operate on the currently active table.
  *
  * \return The return value of the underlying call to osl_add_row().
  */
-int score_add(const struct osl_row *aft_row, long score)
+int score_add(const struct osl_row *aft_row, long score, struct osl_table *t)
 {
        int ret;
        struct osl_object score_objs[NUM_SCORE_COLUMNS];
@@ -112,7 +113,7 @@ int score_add(const struct osl_row *aft_row, long score)
        *(long *)(score_objs[SCORECOL_SCORE].data) = score;
 
 //     PARA_DEBUG_LOG("adding %p\n", *(void **) (score_objs[SCORECOL_AFT_ROW].data));
-       ret = osl(osl_add_row(score_table, score_objs));
+       ret = osl(osl_add_row(t? t : score_table, score_objs));
        if (ret < 0) {
                PARA_ERROR_LOG("%s\n", para_strerror(-ret));
                free(score_objs[SCORECOL_SCORE].data);
@@ -152,7 +153,7 @@ int score_update(const struct osl_row *aft_row, long percent)
        ret = osl(osl_get_nth_row(score_table, SCORECOL_SCORE, new_pos, &rrow));
        if (ret < 0)
                return ret;
-       ret = get_score_of_row(rrow, &new_score);
+       ret = get_score_of_row(score_table, rrow, &new_score);
        if (ret < 0)
                return ret;
        new_score--;
@@ -176,7 +177,7 @@ int get_score_and_aft_row(struct osl_row *score_row, long *score,
                struct osl_row **aft_row)
 {
        struct osl_object obj;
-       int ret = get_score_of_row(score_row, score);
+       int ret = get_score_of_row(score_table, score_row, score);
 
        if (ret < 0)
                return ret;
@@ -187,26 +188,28 @@ int get_score_and_aft_row(struct osl_row *score_row, long *score,
        return 1;
 }
 
-static int get_score_row_from_aft_row(const struct osl_row *aft_row,
-               struct osl_row **score_row)
+static int get_score_row_from_aft_row(struct osl_table *t,
+               const struct osl_row *aft_row, struct osl_row **score_row)
 {
        struct osl_object obj = {.data = (struct osl_row *)aft_row,
                .size = sizeof(aft_row)};
-       return osl(osl_get_row(score_table, SCORECOL_AFT_ROW, &obj, score_row));
+       return osl(osl_get_row(t, SCORECOL_AFT_ROW, &obj, score_row));
 }
 
 /**
  * Call the given function for each row of the score table.
  *
  * \param func Callback, called once per row.
+ * \param t NULL means to use the currently active score table.
  * \param data Passed verbatim to the callback.
  *
  * \return The return value of the underlying call to osl_rbtree_loop(). The
  * loop terminates early if the callback returns negative.
  */
-int score_loop(osl_rbtree_loop_func *func, void *data)
+int score_loop(osl_rbtree_loop_func *func, struct osl_table *t, void *data)
 {
-       return osl(osl_rbtree_loop(score_table, SCORECOL_SCORE, data, func));
+       return osl(osl_rbtree_loop(t? t : score_table, SCORECOL_SCORE, data,
+               func));
 }
 
 /**
@@ -229,7 +232,7 @@ int score_get_best(struct osl_row **aft_row, long *score)
        if (ret < 0)
                return ret;
        *aft_row = obj.data;
-       return get_score_of_row(row, score);
+       return get_score_of_row(score_table, row, score);
 }
 
 /**
@@ -244,7 +247,7 @@ int score_get_best(struct osl_row **aft_row, long *score)
 int score_delete(const struct osl_row *aft_row)
 {
        struct osl_row *score_row;
-       int ret = get_score_row_from_aft_row(aft_row, &score_row);
+       int ret = get_score_row_from_aft_row(score_table, aft_row, &score_row);
 
        if (ret < 0)
                return ret;
@@ -263,7 +266,7 @@ int score_delete(const struct osl_row *aft_row)
 bool row_belongs_to_score_table(const struct osl_row *aft_row)
 {
        struct osl_row *score_row;
-       int ret = get_score_row_from_aft_row(aft_row, &score_row);
+       int ret = get_score_row_from_aft_row(score_table, aft_row, &score_row);
 
        if (ret == -OSL_ERRNO_TO_PARA_ERROR(E_OSL_RB_KEY_NOT_FOUND))
                return false;
@@ -271,30 +274,56 @@ bool row_belongs_to_score_table(const struct osl_row *aft_row)
        return true;
 }
 
-static void score_close(void)
+/**
+ * Free all volatile objects, then close the table.
+ *
+ * \param t As returned from \ref score_open().
+ *
+ * This either succeeds or terminates the calling process.
+ */
+void score_close(struct osl_table *t)
 {
-       osl_close_table(score_table, OSL_FREE_VOLATILE);
-       score_table = NULL;
+       assert(osl_close_table(t? t : score_table, OSL_FREE_VOLATILE) >= 0);
 }
 
-static int score_open(__a_unused const char *dir)
+static void close_global_table(void)
 {
-       return osl(osl_open_table(&score_table_desc, &score_table));
+       score_close(NULL);
+}
+
+static int open_global_table(__a_unused const char *dir)
+{
+       assert(osl(osl_open_table(&score_table_desc, &score_table)) >= 0);
+       return 1;
 }
 
 /**
- * Remove all entries from the score table, but keep the table open.
+ * Allocate a score table instance.
  *
- * \return Standard.
+ * \param result NULL means to open the currently active score table.
+ *
+ * Since the score table does no filesystem I/O, this function always succeeds.
+ * \sa \ref score_close().
+ */
+void score_open(struct osl_table **result)
+{
+       if (result)
+               assert(osl(osl_open_table(&score_table_desc, result)) >= 0);
+       else
+               open_global_table(NULL);
+}
+
+/**
+ * Remove all entries from the score table, but keep the table open.
  */
-int clear_score_table(void)
+void score_clear(void)
 {
-       score_close();
-       return score_open(NULL);
+       close_global_table();
+       open_global_table(NULL);
 }
 
 /** The score table stores (aft row, score) pairs in memory. */
 const struct afs_table_operations score_ops = {
-       .open = score_open,
-       .close = score_close,
+       .open = open_global_table,
+       .close = close_global_table,
 };