+static void subject_relation_insert(GRelation *relation, GNode *node)
+{
+ gchar *subject;
+ MsgInfo *msginfo;
+
+ g_return_if_fail(relation != NULL);
+ g_return_if_fail(node != NULL);
+ msginfo = (MsgInfo *) node->data;
+ g_return_if_fail(msginfo != NULL);
+
+ subject = msginfo->subject;
+ if (subject == NULL)
+ return;
+ subject += subject_get_prefix_length(subject);
+
+ g_relation_insert(relation, subject, node);
+}
+
+static GNode *subject_relation_lookup(GRelation *relation, MsgInfo *msginfo)
+{
+ gchar *subject;
+ GTuples *tuples;
+ GNode *node = NULL;
+
+ g_return_val_if_fail(relation != NULL, NULL);
+
+ subject = msginfo->subject;
+ if (subject == NULL)
+ return NULL;
+ subject += subject_get_prefix_length(subject);
+
+ tuples = g_relation_select(relation, subject, 0);
+ if (tuples == NULL)
+ return NULL;
+
+ if (tuples->len > 0) {
+ int i;
+ GNode *relation_node;
+ MsgInfo *relation_msginfo, *best_msginfo;
+ gboolean match;
+
+ /* check all nodes with the same subject to find the best parent */
+ for (i = 0; i < tuples->len; i++) {
+ relation_node = (GNode *) g_tuples_index(tuples, i, 1);
+ relation_msginfo = (MsgInfo *) relation_node->data;
+ match = FALSE;
+
+ /* best node should be the oldest in the found nodes */
+ /* parent node must not be older then msginfo */
+ if (best_msginfo->date_t < relation_msginfo->date_t &&
+ relation_msginfo->date_t < msginfo->date_t)
+ match = TRUE;
+
+ /* parent node must not be more then thread_by_subject_max_age
+ days older then msginfo */
+ if (abs(difftime(msginfo->date_t, relation_msginfo->date_t)) >
+ prefs_common.thread_by_subject_max_age * 3600 * 24)
+ match = FALSE;
+
+ /* can add new tests for all matching
+ nodes found by subject */
+
+ if (match) {
+ node = relation_node;
+ best_msginfo = relation_msginfo;
+ }
+ }
+ }
+
+ g_tuples_destroy(tuples);
+ return node;
+}
+