changeset 5903:5d0827cd9839 HEAD

Added maildir_filename_sort_cmp() which sorts maildir filenames by time and microseconds. Use it for sorting newly seen files.
author Timo Sirainen <tss@iki.fi>
date Sun, 08 Jul 2007 21:24:57 +0300
parents 0cef1d7a0ce3
children 62ceb6b2b20d
files src/lib-storage/index/maildir/maildir-filename.c src/lib-storage/index/maildir/maildir-filename.h src/lib-storage/index/maildir/maildir-uidlist.c
diffstat 3 files changed, 52 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib-storage/index/maildir/maildir-filename.c	Sun Jul 08 21:22:08 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-filename.c	Sun Jul 08 21:24:57 2007 +0300
@@ -256,3 +256,53 @@
 		return 0;
 	return *s1 - *s2;
 }
+
+static bool maildir_fname_get_usecs(const char *fname, int *usecs_r)
+{
+	int usecs = 0;
+
+	/* Assume we already read the timestamp. Next up is
+	   ".<uniqueness>.<host>". Find usecs inside the uniqueness. */
+	if (*fname != '.')
+		return FALSE;
+
+	fname++;
+	while (*fname != '\0' && *fname != '.' && *fname != MAILDIR_INFO_SEP) {
+		if (*fname++ == 'M') {
+			while (*fname >= '0' && *fname <= '9') {
+				usecs = usecs * 10 + (*fname - '0');
+				fname++;
+			}
+			*usecs_r = usecs;
+			return TRUE;
+		}
+	}
+	return FALSE;
+}
+
+int maildir_filename_sort_cmp(const char *fname1, const char *fname2)
+{
+	const char *s1, *s2;
+	time_t secs1 = 0, secs2 = 0;
+	int ret, usecs1, usecs2;
+
+	/* sort primarily by the timestamp in file name */
+	for (s1 = fname1; *s1 >= '0' && *s1 <= '9'; s1++)
+		secs1 = secs1 * 10 + (*s1 - '0');
+	for (s2 = fname2; *s2 >= '0' && *s2 <= '9'; s2++)
+		secs2 = secs2 * 10 + (*s2 - '0');
+
+	ret = (int)((long)secs1 - (long)secs2);
+	if (ret == 0) {
+		/* sort secondarily by microseconds, if they exist */
+		if (maildir_fname_get_usecs(s1, &usecs1) &&
+		    maildir_fname_get_usecs(s2, &usecs2))
+			ret = usecs1 - usecs2;
+
+		if (ret == 0) {
+			/* fallback to comparing the base file name */
+			ret = maildir_filename_base_cmp(s1, s2);
+		}
+	}
+	return ret;
+}
--- a/src/lib-storage/index/maildir/maildir-filename.h	Sun Jul 08 21:22:08 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-filename.h	Sun Jul 08 21:24:57 2007 +0300
@@ -17,5 +17,6 @@
 
 unsigned int maildir_filename_base_hash(const void *p);
 int maildir_filename_base_cmp(const void *p1, const void *p2);
+int maildir_filename_sort_cmp(const char *fname1, const char *fname2);
 
 #endif
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Sun Jul 08 21:22:08 2007 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Sun Jul 08 21:24:57 2007 +0300
@@ -877,22 +877,8 @@
 static int maildir_time_cmp(const void *p1, const void *p2)
 {
 	const struct maildir_uidlist_rec *const *rec1 = p1, *const *rec2 = p2;
-	const char *s1 = (*rec1)->filename, *s2 = (*rec2)->filename;
-	time_t t1 = 0, t2 = 0;
 
-	/* we have to do numeric comparision, strcmp() will break when
-	   there's different amount of digits (mostly the 999999999 ->
-	   1000000000 change in Sep 9 2001) */
-	while (*s1 >= '0' && *s1 <= '9') {
-		t1 = t1*10 + (*s1 - '0');
-		s1++;
-	}
-	while (*s2 >= '0' && *s2 <= '9') {
-		t2 = t2*10 + (*s2 - '0');
-		s2++;
-	}
-
-	return t1 < t2 ? -1 : t1 > t2 ? 1 : 0;
+	return maildir_filename_sort_cmp((*rec1)->filename, (*rec2)->filename);
 }
 
 static void maildir_uidlist_assign_uids(struct maildir_uidlist_sync_ctx *ctx,