commit b5c5c5c

Paul Martin  ·  2025-01-15 00:40:32 +0000 UTC
parent a016045
Implement faster min_id handling
3 files changed,  +61, -18
M data.c
M snac.h
M data.c
+31, -0
 1@@ -679,6 +679,37 @@ int index_desc_first(FILE *f, char md5[MD5_HEX_SIZE], int skip)
 2     return 1;
 3 }
 4 
 5+int index_asc_first(FILE *f,char md5[MD5_HEX_SIZE], const char *seek_md5)
 6+/* reads the first entry of an ascending index, starting from a given md5 */
 7+{
 8+    fseek(f, SEEK_SET, 0);
 9+    while (fread(md5, MD5_HEX_SIZE, 1, f)) {
10+        md5[MD5_HEX_SIZE - 1] = '\0';
11+        if (strcmp(md5,seek_md5) == 0) {
12+            return index_asc_next(f, md5);
13+        }
14+    }
15+    return 0;
16+}
17+
18+int index_asc_next(FILE *f, char md5[MD5_HEX_SIZE])
19+/* reads the next entry of an ascending index */
20+{
21+    for (;;) {
22+        /* read an md5 */
23+        if (!fread(md5, MD5_HEX_SIZE, 1, f))
24+            return 0;
25+
26+        /* deleted, skip */
27+        if (md5[0] != '-')
28+            break;
29+    }
30+
31+    md5[MD5_HEX_SIZE - 1] = '\0';
32+
33+    return 1;
34+}
35+
36 
37 xs_list *index_list_desc(const char *fn, int skip, int show)
38 /* returns an index as a list, in reverse order */
+28, -18
 1@@ -1339,6 +1339,9 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn
 2     const char *since_id = xs_dict_get(args, "since_id");
 3     const char *min_id   = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */
 4     const char *limit_s  = xs_dict_get(args, "limit");
 5+    int (*iterator)(FILE *, char *);
 6+    int initial_status = 0;
 7+    int ascending = 0;
 8     int limit = 0;
 9     int cnt   = 0;
10 
11@@ -1348,27 +1351,40 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn
12     if (limit == 0)
13         limit = 20;
14 
15-    if (index_desc_first(f, md5, 0)) {
16+    if (min_id) {
17+        iterator = &index_asc_next;
18+        initial_status = index_asc_first(f, md5, MID_TO_MD5(min_id));
19+        ascending = 1;
20+    }
21+    else {
22+        iterator = &index_desc_next;
23+        initial_status = index_desc_first(f, md5, 0);
24+    }
25+
26+    if (initial_status) {
27         do {
28             xs *msg = NULL;
29 
30             /* only return entries older that max_id */
31             if (max_id) {
32-                if (strcmp(md5, MID_TO_MD5(max_id)) == 0)
33+                if (strcmp(md5, MID_TO_MD5(max_id)) == 0) {
34                     max_id = NULL;
35-
36-                continue;
37+                    if (ascending)
38+                        break;
39+                }
40+                if (!ascending)
41+                    continue;
42             }
43 
44             /* only returns entries newer than since_id */
45             if (since_id) {
46-                if (strcmp(md5, MID_TO_MD5(since_id)) == 0)
47-                    break;
48-            }
49-
50-            if (min_id) {
51-                if (strcmp(md5, MID_TO_MD5(min_id)) == 0)
52-                    break;
53+                if (strcmp(md5, MID_TO_MD5(since_id)) == 0) {
54+                    if (!ascending)
55+                        break;
56+                    since_id = NULL;
57+                }
58+                if (ascending)
59+                    continue;
60             }
61 
62             /* get the entry */
63@@ -1440,14 +1456,8 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn
64                 out = xs_list_append(out, st);
65                 cnt++;
66             }
67-            if (min_id) {
68-                while (cnt > limit) {
69-                    out = xs_list_del(out, 0);
70-                    cnt--;
71-                }
72-            }
73 
74-        } while ((min_id || (cnt < limit)) && index_desc_next(f, md5));
75+        } while ((cnt < limit) && (*iterator)(f, md5));
76     }
77 
78     int more = index_desc_next(f, md5);
M snac.h
+2, -0
1@@ -108,6 +108,8 @@ int index_len(const char *fn);
2 xs_list *index_list(const char *fn, int max);
3 int index_desc_next(FILE *f, char md5[MD5_HEX_SIZE]);
4 int index_desc_first(FILE *f, char md5[MD5_HEX_SIZE], int skip);
5+int index_asc_next(FILE *f, char md5[MD5_HEX_SIZE]);
6+int index_asc_first(FILE *f, char md5[MD5_HEX_SIZE], const char *seek_md5);
7 xs_list *index_list_desc(const char *fn, int skip, int show);
8 
9 int object_add(const char *id, const xs_dict *obj);