+2010-10-03 [colin] 3.7.6cvs53
+
+ * src/folder.c
+ * src/folder.h
+ * src/imap.c
+ * src/mh.c
+ * src/procmsg.c
+ Get rid of GRelation which were, mostly, used as
+ GHashTables. Probably fixes bug #2277, 'Segfault when
+ loading inbox for the first time'
+
2010-10-03 [mir] 3.7.6cvs52
* manual/de/dist/html/Makefile.am
( cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/html/Makefile.am; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/html/Makefile.am; cvs diff -u -r 1.1.2.6 -r 1.1.2.7 manual/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/html/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/html/Makefile.am; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/fr/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/html/Makefile.am; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/pl/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/txt/Makefile.am; ) > 3.7.6cvs50.patchset
( cvs diff -u -r 1.53.2.36 -r 1.53.2.37 po/POTFILES.in; ) > 3.7.6cvs51.patchset
( cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/html/Makefile.am; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.1 -r 1.1.2.2 manual/de/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/html/Makefile.am; cvs diff -u -r 1.1.2.6 -r 1.1.2.7 manual/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.5 -r 1.1.2.6 manual/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/html/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.2 -r 1.1.2.3 manual/es/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/html/Makefile.am; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/fr/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/fr/dist/txt/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/html/Makefile.am; cvs diff -u -r 1.1.2.4 -r 1.1.2.5 manual/pl/dist/pdf/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/ps/Makefile.am; cvs diff -u -r 1.1.2.3 -r 1.1.2.4 manual/pl/dist/txt/Makefile.am; ) > 3.7.6cvs52.patchset
+( cvs diff -u -r 1.213.2.196 -r 1.213.2.197 src/folder.c; cvs diff -u -r 1.87.2.61 -r 1.87.2.62 src/folder.h; cvs diff -u -r 1.179.2.251 -r 1.179.2.252 src/imap.c; cvs diff -u -r 1.79.2.69 -r 1.79.2.70 src/mh.c; cvs diff -u -r 1.150.2.115 -r 1.150.2.116 src/procmsg.c; ) > 3.7.6cvs53.patchset
MICRO_VERSION=6
INTERFACE_AGE=0
BINARY_AGE=0
-EXTRA_VERSION=52
+EXTRA_VERSION=53
EXTRA_RELEASE=
EXTRA_GTK2_VERSION=
static gint syncronize_flags(FolderItem *item, MsgInfoList *msglist)
{
- GRelation *relation;
+ GHashTable *relation;
gint ret = 0;
GSList *cur;
if (item->no_select)
return 0;
- relation = g_relation_new(2);
- g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
+ relation = g_hash_table_new(g_direct_hash, g_direct_equal);
if ((ret = item->folder->klass->get_flags(
item->folder, item, msglist, relation)) == 0) {
- GTuples *tuples;
+ gpointer data, old_key;
MsgInfo *msginfo;
MsgPermFlags permflags = 0;
- gboolean skip;
folder_item_update_freeze();
folder_item_set_batch(item, TRUE);
for (cur = msglist; cur != NULL; cur = g_slist_next(cur)) {
msginfo = (MsgInfo *) cur->data;
- tuples = g_relation_select(relation, msginfo, 0);
- skip = tuples->len < 1;
- if (!skip)
- permflags = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
- g_tuples_destroy(tuples);
- if (skip)
- continue;
-
- if (msginfo->flags.perm_flags != permflags) {
- procmsg_msginfo_change_flags(msginfo,
- permflags & ~msginfo->flags.perm_flags, 0,
- ~permflags & msginfo->flags.perm_flags, 0);
+ if (g_hash_table_lookup_extended(relation, msginfo, &old_key, &data)) {
+ permflags = GPOINTER_TO_INT(data);
+
+ if (msginfo->flags.perm_flags != permflags) {
+ procmsg_msginfo_change_flags(msginfo,
+ permflags & ~msginfo->flags.perm_flags, 0,
+ ~permflags & msginfo->flags.perm_flags, 0);
+ }
}
}
folder_item_set_batch(item, FALSE);
folder_item_update_thaw();
}
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
return ret;
}
Folder *folder;
gint ret, num, lastnum = -1;
GSList *file_cur;
- GRelation *relation;
+ GHashTable *relation;
MsgFileInfo *fileinfo = NULL;
gboolean folderscan = FALSE;
folder = dest->folder;
- relation = g_relation_new(2);
- g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
+ relation = g_hash_table_new(g_direct_hash, g_direct_equal);
if (folder->klass->add_msgs != NULL) {
ret = folder->klass->add_msgs(folder, dest, file_list, relation);
if (ret < 0) {
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
return ret;
}
} else {
ret = folder->klass->add_msg(folder, dest, fileinfo->file, fileinfo->flags);
if (ret < 0) {
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
return ret;
}
- g_relation_insert(relation, fileinfo, GINT_TO_POINTER(ret));
+ g_hash_table_insert(relation, fileinfo, GINT_TO_POINTER(ret));
}
}
for (file_cur = file_list; file_cur != NULL; file_cur = g_slist_next(file_cur)) {
- GTuples *tuples;
+ gpointer data, old_key;
fileinfo = (MsgFileInfo *) file_cur->data;
- tuples = g_relation_select(relation, fileinfo, 0);
- num = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
- g_tuples_destroy(tuples);
+ if (g_hash_table_lookup_extended(relation, fileinfo, &old_key, &data))
+ num = GPOINTER_TO_INT(data);
+ else
+ num = -1;
if (num >= 0) {
MsgInfo *newmsginfo;
}
}
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
return lastnum;
}
return F_MOVE_OK;
}
+struct find_data
+{
+ gboolean found;
+};
+static void find_num(gpointer key, gpointer value, gpointer data)
+{
+ struct find_data *fdata = (struct find_data *)data;
+ if (GPOINTER_TO_INT(value) == 0)
+ fdata->found = TRUE;
+}
+
+static gboolean some_msgs_have_zero_num(GHashTable *hashtable)
+{
+ struct find_data fdata;
+
+ fdata.found = FALSE;
+ g_hash_table_foreach(hashtable, find_num, &fdata);
+
+ return fdata.found;
+}
+
/**
* Copy a list of message to a new folder and remove
* source messages if wanted
GSList *l;
gint num, lastnum = -1;
gboolean folderscan = FALSE;
- GRelation *relation;
+ GHashTable *relation;
GSList *not_moved = NULL;
gint total = 0, curmsg = 0;
MsgInfo *msginfo = NULL;
return queue_err ? -1:0;
}
- relation = g_relation_new(2);
- g_relation_index(relation, 0, g_direct_hash, g_direct_equal);
- g_relation_index(relation, 1, g_direct_hash, g_direct_equal);
+ relation = g_hash_table_new(g_direct_hash, g_direct_equal);
for (l = msglist ; l != NULL ; l = g_slist_next(l)) {
MsgInfo * msginfo = (MsgInfo *) l->data;
*/
if (folder->klass->copy_msgs != NULL) {
if (folder->klass->copy_msgs(folder, dest, msglist, relation) < 0) {
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
return -1;
}
} else {
if (l != NULL) {
msginfo = (MsgInfo *) l->data;
if (msginfo != NULL && msginfo->folder == dest) {
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
return -1;
}
}
num = folder->klass->copy_msg(folder, dest, msginfo);
if (num > 0)
- g_relation_insert(relation, msginfo, GINT_TO_POINTER(num));
+ g_hash_table_insert(relation, msginfo, GINT_TO_POINTER(num));
else
not_moved = g_slist_prepend(not_moved, msginfo);
}
relation);
}
for (l = msglist; l != NULL; l = g_slist_next(l)) {
- GTuples *tuples;
+ gpointer old_key, data;
msginfo = (MsgInfo *) l->data;
item = msginfo->folder;
- tuples = g_relation_select(relation, msginfo, 0);
- if (tuples) {
- if (tuples->len)
- num = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
- else
- num = 0;
- g_tuples_destroy(tuples);
- } else {
+ if (g_hash_table_lookup_extended(relation, msginfo, &old_key, &data))
+ num = GPOINTER_TO_INT(data);
+ else
num = -1;
- }
if (g_slist_find(not_moved, msginfo))
continue;
* Fetch new MsgInfos for new messages in dest folder,
* add them to the msgcache and update folder message counts
*/
- if (g_relation_count(relation, GINT_TO_POINTER(0), 1) > 0) {
+ if (some_msgs_have_zero_num(relation)) {
folder_item_scan_full(dest, FALSE);
folderscan = TRUE;
}
folder_item_set_batch(dest, TRUE);
for (l = msglist; l != NULL; l = g_slist_next(l)) {
MsgInfo *msginfo = (MsgInfo *) l->data;
- GTuples *tuples;
+ gpointer data, old_key;
if (!msginfo)
continue;
- tuples = g_relation_select(relation, msginfo, 0);
- if (tuples && tuples->len > 0) {
- num = GPOINTER_TO_INT(g_tuples_index(tuples, 0, 1));
- g_tuples_destroy(tuples);
- } else {
- num = 0;
- if (tuples)
- g_tuples_destroy(tuples);
- }
+
+ if (g_hash_table_lookup_extended(relation, msginfo, &old_key, &data))
+ num = GPOINTER_TO_INT(data);
+ else
+ num = -1;
+
statusbar_progress_all(curmsg++,total, 100);
if (curmsg % 100 == 0)
GTK_EVENTS_FLUSH();
statusbar_progress_all(0,0,0);
statusbar_pop_all();
- g_relation_destroy(relation);
+ g_hash_table_destroy(relation);
if (not_moved != NULL) {
g_slist_free(not_moved);
return -1;
gint (*add_msgs) (Folder *folder,
FolderItem *dest,
GSList *file_list,
- GRelation *relation);
+ GHashTable *relation);
/**
* Copy a message to a FolderItem
*
gint (*copy_msgs) (Folder *folder,
FolderItem *dest,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
/**
* Remove a message from a \c FolderItem.
*
gint (*remove_msgs) (Folder *folder,
FolderItem *item,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
gint (*expunge) (Folder *folder,
FolderItem *item);
/**
gint (*get_flags) (Folder *folder,
FolderItem *item,
MsgInfoList *msglist,
- GRelation *msgflags);
+ GHashTable *msgflags);
/* Sets batch mode for a FolderItem. It means that numerous flags updates
* could follow, and the FolderClass implementation can cache them in order
static gint imap_add_msgs (Folder *folder,
FolderItem *dest,
GSList *file_list,
- GRelation *relation);
+ GHashTable *relation);
static gint imap_copy_msg (Folder *folder,
FolderItem *dest,
static gint imap_copy_msgs (Folder *folder,
FolderItem *dest,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
static gint imap_remove_msg (Folder *folder,
FolderItem *item,
static gint imap_remove_msgs (Folder *folder,
FolderItem *dest,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
static gint imap_expunge (Folder *folder,
FolderItem *dest);
static gint imap_remove_all_msg (Folder *folder,
static gint imap_do_copy_msgs (Folder *folder,
FolderItem *dest,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
static void imap_delete_all_cached_messages (FolderItem *item);
static void imap_set_batch (Folder *folder,
static gint imap_get_flags (Folder *folder,
FolderItem *item,
MsgInfoList *msglist,
- GRelation *msgflags);
+ GHashTable *msgflags);
static gchar *imap_folder_get_path (Folder *folder);
static gchar *imap_item_get_path (Folder *folder,
FolderItem *item);
}
static gint imap_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
- GRelation *relation)
+ GHashTable *relation)
{
gchar *destdir;
IMAPSession *session;
}
if (relation != NULL)
- g_relation_insert(relation, fileinfo->msginfo != NULL ?
+ g_hash_table_insert(relation, fileinfo->msginfo != NULL ?
(gpointer) fileinfo->msginfo : (gpointer) fileinfo,
GINT_TO_POINTER(new_uid));
if (last_uid < new_uid) {
return result;
}
static gint imap_do_copy_msgs(Folder *folder, FolderItem *dest,
- MsgInfoList *msglist, GRelation *relation)
+ MsgInfoList *msglist, GHashTable *relation)
{
FolderItem *src;
gchar *destdir;
if (hashval != NULL) {
gint num = GPOINTER_TO_INT(hashval);
- g_relation_insert(relation, msginfo,
+ g_hash_table_insert(relation, msginfo,
GINT_TO_POINTER(num));
if (num > last_num)
last_num = num;
g_free(cache_path);
}
} else
- g_relation_insert(relation, msginfo,
+ g_hash_table_insert(relation, msginfo,
GINT_TO_POINTER(0));
}
statusbar_pop_all();
}
static gint imap_copy_msgs(Folder *folder, FolderItem *dest,
- MsgInfoList *msglist, GRelation *relation)
+ MsgInfoList *msglist, GHashTable *relation)
{
MsgInfo *msginfo;
gint ret;
static gint imap_do_remove_msgs(Folder *folder, FolderItem *dest,
- MsgInfoList *msglist, GRelation *relation)
+ MsgInfoList *msglist, GHashTable *relation)
{
gchar *destdir, *dir;
GSList *numlist = NULL, *cur;
}
static gint imap_remove_msgs(Folder *folder, FolderItem *dest,
- MsgInfoList *msglist, GRelation *relation)
+ MsgInfoList *msglist, GHashTable *relation)
{
MsgInfo *msginfo;
Folder *folder;
FolderItem *item;
MsgInfoList *msginfo_list;
- GRelation *msgflags;
+ GHashTable *msgflags;
gboolean full_search;
gboolean done;
} get_flags_data;
Folder *folder = stuff->folder;
FolderItem *fitem = (FolderItem *) stuff->item;
MsgInfoList *msginfo_list = stuff->msginfo_list;
- GRelation *msgflags = stuff->msgflags;
+ GHashTable *msgflags = stuff->msgflags;
GSList *elem;
carray * lep_uidtab;
IMAPSession *session;
}
}
- g_relation_insert(msgflags, msginfo, GINT_TO_POINTER(flags));
+ g_hash_table_insert(msgflags, msginfo, GINT_TO_POINTER(flags));
}
if (got_alien_tags) {
}
static gint imap_get_flags(Folder *folder, FolderItem *item,
- MsgInfoList *msginfo_list, GRelation *msgflags)
+ MsgInfoList *msginfo_list, GHashTable *msgflags)
{
gint result;
get_flags_data *data = g_new0(get_flags_data, 1);
static gint mh_add_msgs (Folder *folder,
FolderItem *dest,
GSList *file_list,
- GRelation *relation);
+ GHashTable *relation);
static gint mh_copy_msg (Folder *folder,
FolderItem *dest,
MsgInfo *msginfo);
static gint mh_copy_msgs (Folder *folder,
FolderItem *dest,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
static gint mh_remove_msg (Folder *folder,
FolderItem *item,
gint num);
static gint mh_remove_msgs (Folder *folder,
FolderItem *item,
MsgInfoList *msglist,
- GRelation *relation);
+ GHashTable *relation);
static gint mh_remove_all_msg (Folder *folder,
FolderItem *item);
static gboolean mh_is_msg_changed (Folder *folder,
FolderItem *item);
#if 0
static gint mh_get_flags (Folder *folder, FolderItem *item,
- MsgInfoList *msginfo_list, GRelation *msgflags);
+ MsgInfoList *msginfo_list, GHashTable *msgflags);
#endif
static void mh_write_sequences (FolderItem *item, gboolean remove_unseen);
}
static gint mh_add_msgs(Folder *folder, FolderItem *dest, GSList *file_list,
- GRelation *relation)
+ GHashTable *relation)
{
gchar *destfile;
GSList *cur;
#endif
if (relation != NULL)
- g_relation_insert(relation, fileinfo, GINT_TO_POINTER(dest->last_num + 1));
+ g_hash_table_insert(relation, fileinfo, GINT_TO_POINTER(dest->last_num + 1));
g_free(destfile);
dest->last_num++;
}
}
static gint mh_copy_msgs(Folder *folder, FolderItem *dest, MsgInfoList *msglist,
- GRelation *relation)
+ GHashTable *relation)
{
gboolean dest_need_scan = FALSE;
gboolean src_need_scan = FALSE;
if (filemode & S_IRGRP) filemode |= S_IWGRP;
if (filemode & S_IROTH) filemode |= S_IWOTH;
}
- if (relation)
- g_relation_insert(relation, msginfo, GINT_TO_POINTER(dest->last_num+1));
+ if (relation) {
+ if (g_hash_table_lookup(relation, msginfo) != NULL)
+ g_warning("already in : %p", msginfo);
+
+ g_hash_table_insert(relation, msginfo, GINT_TO_POINTER(dest->last_num+1));
+ }
g_free(srcfile);
g_free(destfile);
dest->last_num++;
}
static gint mh_remove_msgs(Folder *folder, FolderItem *item,
- MsgInfoList *msglist, GRelation *relation)
+ MsgInfoList *msglist, GHashTable *relation)
{
gboolean need_scan = FALSE;
gchar *path, *file;
return seq_name;
}
-#if 0
-static gint mh_get_flags(Folder *folder, FolderItem *item,
- MsgInfoList *msginfo_list, GRelation *msgflags)
-{
- gchar *mh_sequences_filename;
- FILE *mh_sequences_file;
- gchar buf[BUFFSIZE];
- gchar *unseen_list = NULL;
- gchar *path;
- MsgInfoList *mcur = NULL;
-/*
- GTimer *timer = g_timer_new();
- g_timer_start(timer);
-*/
- if (!item)
- return 0;
-
- /* don't update from .mh_sequences if the item's opened: mails may have
- * been marked read/unread and it's not yet written in the file. */
- if (item->opened)
- return 0;
-
- path = folder_item_get_path(item);
-
- mh_sequences_filename = g_strconcat(path, G_DIR_SEPARATOR_S,
- ".mh_sequences", NULL);
- g_free(path);
- if ((mh_sequences_file = g_fopen(mh_sequences_filename, "r+b")) != NULL) {
- while (fgets(buf, sizeof(buf), mh_sequences_file) != NULL) {
- if (!strncmp(buf, get_unseen_seq_name(), strlen(get_unseen_seq_name()))) {
- unseen_list = g_strdup(buf+strlen(get_unseen_seq_name()));
- break;
- }
- }
- fclose(mh_sequences_file);
- }
-
- g_free(mh_sequences_filename);
-
- if (unseen_list) {
- gchar *cur = NULL;
- gchar *token = NULL, *next = NULL, *boundary = NULL;
- gint num = 0;
- GHashTable *unseen_table = g_hash_table_new(g_direct_hash, g_direct_equal);
-
- cur = unseen_list = strretchomp(unseen_list);
- debug_print("found unseen list in .mh_sequences: %s\n", unseen_list);
-next_token:
- while (*cur && *cur == ' ')
- cur++;
-
- if ((next = strchr(cur, ' ')) != NULL) {
- token = cur;
- cur = next+1;
- *next = '\0';
- } else {
- token = cur;
- cur = NULL;
- }
-
- if ((boundary = strchr(token, '-')) != NULL) {
- gchar *start, *end;
- int i;
- start = token;
- end = boundary+1;
- *boundary='\0';
- for (i = atoi(start); i <= atoi(end); i++) {
- g_hash_table_insert(unseen_table, GINT_TO_POINTER(i), GINT_TO_POINTER(1));
- }
- } else if ((num = atoi(token)) > 0) {
- g_hash_table_insert(unseen_table, GINT_TO_POINTER(num), GINT_TO_POINTER(1));
- }
-
- if (cur)
- goto next_token;
- for (mcur = msginfo_list; mcur; mcur = mcur->next) {
- MsgInfo *msginfo = (MsgInfo *)mcur->data;
- MsgPermFlags flags = msginfo->flags.perm_flags;
- if (g_hash_table_lookup(unseen_table, GINT_TO_POINTER(msginfo->msgnum))) {
- flags |= MSG_UNREAD;
- } else if (!(flags & MSG_NEW)) { /* don't mark new msgs as read */
- flags &= ~(MSG_UNREAD);
- }
- if (flags != msginfo->flags.perm_flags)
- g_relation_insert(msgflags, msginfo, GINT_TO_POINTER(flags));
- }
- g_hash_table_destroy(unseen_table);
- g_free(unseen_list);
- }
-/*
- g_timer_stop(timer);
- g_print("mh_get_flags: %f secs\n", g_timer_elapsed(timer, NULL));
- g_timer_destroy(timer);
-*/
- return 0;
-}
-#endif
-
static void mh_write_sequences(FolderItem *item, gboolean remove_unseen)
{
gchar *mh_sequences_old, *mh_sequences_new;
/* CLAWS subject threading:
in the first round it inserts subject lines in a
- relation (subject <-> node)
+ hashtable (subject <-> node)
the second round finishes the threads by attaching
matching subject lines to the one found in the
- relation. will use the oldest node with the same
+ hashtable. will use the oldest node with the same
subject that is not more then thread_by_subject_max_age
- days old (see subject_relation_lookup)
+ days old (see subject_hashtable_lookup)
*/
-static void subject_relation_insert(GRelation *relation, GNode *node)
+static void subject_hashtable_insert(GHashTable *hashtable, GNode *node)
{
gchar *subject;
MsgInfo *msginfo;
+ GSList *list = NULL;
- cm_return_if_fail(relation != NULL);
+ cm_return_if_fail(hashtable != NULL);
cm_return_if_fail(node != NULL);
msginfo = (MsgInfo *) node->data;
cm_return_if_fail(msginfo != NULL);
subject = msginfo->subject;
if (subject == NULL)
return;
+
subject += subject_get_prefix_length(subject);
- g_relation_insert(relation, subject, node);
+ list = g_hash_table_lookup(hashtable, subject);
+ list = g_slist_prepend(list, node);
+ g_hash_table_insert(hashtable, subject, list);
}
-static GNode *subject_relation_lookup(GRelation *relation, MsgInfo *msginfo)
+static GNode *subject_hashtable_lookup(GHashTable *hashtable, MsgInfo *msginfo)
{
gchar *subject;
- GTuples *tuples;
- GNode *node = NULL;
+ GSList *list, *cur;
+ GNode *node = NULL, *hashtable_node = NULL;
gint prefix_length;
+ MsgInfo *hashtable_msginfo = NULL, *best_msginfo = NULL;
+ gboolean match;
- cm_return_val_if_fail(relation != NULL, NULL);
+ cm_return_val_if_fail(hashtable != NULL, NULL);
subject = msginfo->subject;
if (subject == NULL)
return NULL;
subject += prefix_length;
- tuples = g_relation_select(relation, subject, 0);
- if (tuples == NULL)
+ list = g_hash_table_lookup(hashtable, subject);
+ if (list == NULL)
return NULL;
- if (tuples->len > 0) {
- int i;
- GNode *relation_node;
- MsgInfo *relation_msginfo = NULL, *best_msginfo = NULL;
- 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;
+ /* check all nodes with the same subject to find the best parent */
+ for (cur = list; cur; cur = cur->next) {
+ hashtable_node = (GNode *)cur->data;
+ hashtable_msginfo = (MsgInfo *) hashtable_node->data;
+ match = FALSE;
+
+ /* best node should be the oldest in the found nodes */
+ /* parent node must not be older then msginfo */
+ if ((hashtable_msginfo->date_t < msginfo->date_t) &&
+ ((best_msginfo == NULL) ||
+ (best_msginfo->date_t > hashtable_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, hashtable_msginfo->date_t)) >
+ prefs_common.thread_by_subject_max_age * 3600 * 24)
match = FALSE;
- /* best node should be the oldest in the found nodes */
- /* parent node must not be older then msginfo */
- if ((relation_msginfo->date_t < msginfo->date_t) &&
- ((best_msginfo == NULL) ||
- (best_msginfo->date_t > relation_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;
- }
- }
+ /* can add new tests for all matching
+ nodes found by subject */
+
+ if (match) {
+ node = hashtable_node;
+ best_msginfo = hashtable_msginfo;
+ }
}
- g_tuples_destroy(tuples);
return node;
}
+static void subject_hashtable_free(gpointer key, gpointer value, gpointer data)
+{
+ g_slist_free(value);
+}
+
/* return the reversed thread tree */
GNode *procmsg_get_thread_tree(GSList *mlist)
{
GNode *root, *parent, *node, *next;
GHashTable *msgid_table;
- GRelation *subject_relation = NULL;
+ GHashTable *subject_hashtable = NULL;
MsgInfo *msginfo;
const gchar *msgid;
GSList *reflist;
msgid_table = g_hash_table_new(g_str_hash, g_str_equal);
if (prefs_common.thread_by_subject) {
- subject_relation = g_relation_new(2);
- g_relation_index(subject_relation, 0, g_str_hash, g_str_equal);
+ subject_hashtable = g_hash_table_new(g_str_hash, g_str_equal);
}
for (; mlist != NULL; mlist = mlist->next) {
if ((msgid = msginfo->msgid) && g_hash_table_lookup(msgid_table, msgid) == NULL)
g_hash_table_insert(msgid_table, (gchar *)msgid, node);
- /* CLAWS: add subject to relation (without prefix) */
+ /* CLAWS: add subject to hashtable (without prefix) */
if (prefs_common.thread_by_subject) {
- subject_relation_insert(subject_relation, node);
+ subject_hashtable_insert(subject_hashtable, node);
}
}
next = node->next;
msginfo = (MsgInfo *) node->data;
- parent = subject_relation_lookup(subject_relation, msginfo);
+ parent = subject_hashtable_lookup(subject_hashtable, msginfo);
/* the node may already be threaded by IN-REPLY-TO, so go up
* in the tree to
}
if (prefs_common.thread_by_subject)
- g_relation_destroy(subject_relation);
+ {
+ g_hash_table_foreach(subject_hashtable, subject_hashtable_free, NULL);
+ g_hash_table_destroy(subject_hashtable);
+ }
g_hash_table_destroy(msgid_table);
END_TIMING();
g_strchomp(buf);
if (buf[strlen(buf) - 1] != '&') strcat(buf, "&");
- system(buf);
+ if (system(buf) == -1)
+ g_warning("system(%s) failed.", buf);
}
MsgInfo *procmsg_msginfo_new_ref(MsgInfo *msginfo)