commit b5c5c5cb9e1c728a83596dcc7c4191d012fe1332
parent a016045a8fb80e4accad618c60b987bad708f45e
Author: Paul Martin <pm@nowster.org.uk>
Date: Wed, 15 Jan 2025 00:40:32 +0000
Implement faster min_id handling
Diffstat:
M | data.c | | | 31 | +++++++++++++++++++++++++++++++ |
M | mastoapi.c | | | 46 | ++++++++++++++++++++++++++++------------------ |
M | snac.h | | | 2 | ++ |
3 files changed, 61 insertions(+), 18 deletions(-)
diff --git a/data.c b/data.c
@@ -679,6 +679,37 @@ int index_desc_first(FILE *f, char md5[MD5_HEX_SIZE], int skip)
return 1;
}
+int index_asc_first(FILE *f,char md5[MD5_HEX_SIZE], const char *seek_md5)
+/* reads the first entry of an ascending index, starting from a given md5 */
+{
+ fseek(f, SEEK_SET, 0);
+ while (fread(md5, MD5_HEX_SIZE, 1, f)) {
+ md5[MD5_HEX_SIZE - 1] = '\0';
+ if (strcmp(md5,seek_md5) == 0) {
+ return index_asc_next(f, md5);
+ }
+ }
+ return 0;
+}
+
+int index_asc_next(FILE *f, char md5[MD5_HEX_SIZE])
+/* reads the next entry of an ascending index */
+{
+ for (;;) {
+ /* read an md5 */
+ if (!fread(md5, MD5_HEX_SIZE, 1, f))
+ return 0;
+
+ /* deleted, skip */
+ if (md5[0] != '-')
+ break;
+ }
+
+ md5[MD5_HEX_SIZE - 1] = '\0';
+
+ return 1;
+}
+
xs_list *index_list_desc(const char *fn, int skip, int show)
/* returns an index as a list, in reverse order */
diff --git a/mastoapi.c b/mastoapi.c
@@ -1339,6 +1339,9 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn
const char *since_id = xs_dict_get(args, "since_id");
const char *min_id = xs_dict_get(args, "min_id"); /* unsupported old-to-new navigation */
const char *limit_s = xs_dict_get(args, "limit");
+ int (*iterator)(FILE *, char *);
+ int initial_status = 0;
+ int ascending = 0;
int limit = 0;
int cnt = 0;
@@ -1348,27 +1351,40 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn
if (limit == 0)
limit = 20;
- if (index_desc_first(f, md5, 0)) {
+ if (min_id) {
+ iterator = &index_asc_next;
+ initial_status = index_asc_first(f, md5, MID_TO_MD5(min_id));
+ ascending = 1;
+ }
+ else {
+ iterator = &index_desc_next;
+ initial_status = index_desc_first(f, md5, 0);
+ }
+
+ if (initial_status) {
do {
xs *msg = NULL;
/* only return entries older that max_id */
if (max_id) {
- if (strcmp(md5, MID_TO_MD5(max_id)) == 0)
+ if (strcmp(md5, MID_TO_MD5(max_id)) == 0) {
max_id = NULL;
-
- continue;
+ if (ascending)
+ break;
+ }
+ if (!ascending)
+ continue;
}
/* only returns entries newer than since_id */
if (since_id) {
- if (strcmp(md5, MID_TO_MD5(since_id)) == 0)
- break;
- }
-
- if (min_id) {
- if (strcmp(md5, MID_TO_MD5(min_id)) == 0)
- break;
+ if (strcmp(md5, MID_TO_MD5(since_id)) == 0) {
+ if (!ascending)
+ break;
+ since_id = NULL;
+ }
+ if (ascending)
+ continue;
}
/* get the entry */
@@ -1440,14 +1456,8 @@ xs_list *mastoapi_timeline(snac *user, const xs_dict *args, const char *index_fn
out = xs_list_append(out, st);
cnt++;
}
- if (min_id) {
- while (cnt > limit) {
- out = xs_list_del(out, 0);
- cnt--;
- }
- }
- } while ((min_id || (cnt < limit)) && index_desc_next(f, md5));
+ } while ((cnt < limit) && (*iterator)(f, md5));
}
int more = index_desc_next(f, md5);
diff --git a/snac.h b/snac.h
@@ -108,6 +108,8 @@ int index_len(const char *fn);
xs_list *index_list(const char *fn, int max);
int index_desc_next(FILE *f, char md5[MD5_HEX_SIZE]);
int index_desc_first(FILE *f, char md5[MD5_HEX_SIZE], int skip);
+int index_asc_next(FILE *f, char md5[MD5_HEX_SIZE]);
+int index_asc_first(FILE *f, char md5[MD5_HEX_SIZE], const char *seek_md5);
xs_list *index_list_desc(const char *fn, int skip, int show);
int object_add(const char *id, const xs_dict *obj);