Skip to content

Commit 67eb56a

Browse files
committed
ctl_conversationsdb: buffers
1 parent 7240792 commit 67eb56a

File tree

1 file changed

+45
-42
lines changed

1 file changed

+45
-42
lines changed

imap/ctl_conversationsdb.c

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -448,8 +448,8 @@ struct cursor
448448
{
449449
struct db *db;
450450
struct txn **txnp;
451-
const char *key; size_t keylen;
452-
const char *data; size_t datalen;
451+
struct buf keybuf;
452+
struct buf valbuf;
453453
int err;
454454
};
455455

@@ -463,24 +463,22 @@ static void cursor_init(struct cursor *c,
463463

464464
static int cursor_next(struct cursor *c)
465465
{
466-
if (!c->err)
466+
if (!c->err) {
467+
const char *key = NULL;
468+
size_t keylen = 0;
469+
const char *val = NULL;
470+
size_t vallen = 0;
467471
c->err = cyrusdb_fetchnext(c->db,
468-
c->key, c->keylen,
469-
&c->key, &c->keylen,
470-
&c->data, &c->datalen,
472+
c->keybuf.s, c->keybuf.len,
473+
&key, &keylen,
474+
&val, &vallen,
471475
c->txnp);
476+
buf_setmap(&c->keybuf, key, keylen);
477+
buf_setmap(&c->valbuf, val, vallen);
478+
}
472479
return c->err;
473480
}
474481

475-
static int blob_compare(const char *a, size_t alen,
476-
const char *b, size_t blen)
477-
{
478-
int d = memcmp(a, b, MIN(alen, blen));
479-
if (!d)
480-
d = alen - blen;
481-
return d;
482-
}
483-
484482
static int next_diffable_record(struct cursor *c)
485483
{
486484
for (;;)
@@ -490,11 +488,11 @@ static int next_diffable_record(struct cursor *c)
490488

491489
/* skip < records, they won't be in the
492490
* temp database and we don't care so much */
493-
if (c->key[0] == '<')
491+
if (c->keybuf.s[0] == '<')
494492
continue;
495493

496494
/* Subject, not re-calculated */
497-
if (c->key[0] == 'S')
495+
if (c->keybuf.s[0] == 'S')
498496
continue;
499497

500498
return 0;
@@ -517,13 +515,13 @@ static unsigned int diff_records(struct conversations_state *a,
517515
rb = cursor_next(&cb);
518516

519517
while (!ra || !rb) {
520-
keydelta = blob_compare(ca.key, ca.keylen, cb.key, cb.keylen);
518+
keydelta = buf_cmp(&ca.keybuf, &cb.keybuf);
521519
if (rb || keydelta < 0) {
522520
if (ra) break;
523521
ndiffs++;
524522
if (verbose)
525523
printf("REALONLY: \"%.*s\" data \"%.*s\"\n",
526-
(int)ca.keylen, ca.key, (int)ca.datalen, ca.data);
524+
(int)ca.keybuf.len, ca.keybuf.s, (int)ca.valbuf.len, ca.valbuf.s);
527525
ra = next_diffable_record(&ca);
528526
continue;
529527
}
@@ -532,26 +530,31 @@ static unsigned int diff_records(struct conversations_state *a,
532530
ndiffs++;
533531
if (verbose)
534532
printf("TEMPONLY: \"%.*s\" data \"%.*s\"\n",
535-
(int)cb.keylen, cb.key, (int)cb.datalen, cb.data);
533+
(int)cb.keybuf.len, cb.keybuf.s, (int)cb.valbuf.len, cb.valbuf.s);
536534
rb = next_diffable_record(&cb);
537535
continue;
538536
}
539537

540538
/* both exist an are the same key */
541-
delta = blob_compare(ca.data, ca.datalen, cb.data, cb.datalen);
539+
delta = buf_cmp(&ca.valbuf, &cb.valbuf);
542540
if (delta) {
543541
ndiffs++;
544542
if (verbose)
545543
printf("REAL: \"%.*s\" data \"%.*s\"\n"
546544
"TEMP: \"%.*s\" data \"%.*s\"\n",
547-
(int)ca.keylen, ca.key, (int)ca.datalen, ca.data,
548-
(int)cb.keylen, cb.key, (int)cb.datalen, cb.data);
545+
(int)ca.keybuf.len, ca.keybuf.s, (int)ca.valbuf.len, ca.valbuf.s,
546+
(int)cb.keybuf.len, cb.keybuf.s, (int)cb.valbuf.len, cb.valbuf.s);
549547
}
550548

551549
ra = next_diffable_record(&ca);
552550
rb = next_diffable_record(&cb);
553551
}
554552

553+
buf_free(&ca.keybuf);
554+
buf_free(&ca.valbuf);
555+
buf_free(&cb.keybuf);
556+
buf_free(&cb.valbuf);
557+
555558
return ndiffs;
556559
}
557560

@@ -570,20 +573,20 @@ static int fix_modseqs(struct conversations_state *a,
570573
rb = cursor_next(&cb);
571574

572575
while (!ra || !rb) {
573-
keydelta = blob_compare(ca.key, ca.keylen, cb.key, cb.keylen);
576+
keydelta = buf_cmp(&ca.keybuf, &cb.keybuf);
574577
if (rb || keydelta < 0) {
575578
if (ra) break;
576-
if (ca.key[0] == 'F') {
579+
if (ca.keybuf.s[0] == 'F') {
577580
conv_status_t status = CONV_STATUS_INIT;
578581
/* need to add record if it's zero */
579-
r = conversation_parsestatus(ca.data, ca.datalen, &status);
582+
r = conversation_parsestatus(ca.valbuf.s, ca.valbuf.len, &status);
580583
if (r) return r;
581584
if (status.threadexists == 0) {
582-
r = conversation_storestatus(b, ca.key, ca.keylen, &status);
585+
r = conversation_storestatus(b, ca.keybuf.s, ca.keybuf.len, &status);
583586
if (r) {
584587
fprintf(stderr, "Failed to store conversations "
585588
"record \"%.*s\" to %s: %s, giving up\n",
586-
(int)ca.keylen, ca.key,
589+
(int)ca.keybuf.len, ca.keybuf.s,
587590
b->path, error_message(r));
588591
return r;
589592
}
@@ -600,65 +603,65 @@ static int fix_modseqs(struct conversations_state *a,
600603
}
601604

602605
/* folders? Just modseq check */
603-
if (ca.key[0] == 'F') {
606+
if (ca.keybuf.s[0] == 'F') {
604607
/* check if modseq is higher for real */
605608
conv_status_t statusa = CONV_STATUS_INIT;
606609
conv_status_t statusb = CONV_STATUS_INIT;
607610
/* need to add record if it's zero */
608-
r = conversation_parsestatus(ca.data, ca.datalen, &statusa);
611+
r = conversation_parsestatus(ca.valbuf.s, ca.valbuf.len, &statusa);
609612
if (r) {
610613
fprintf(stderr, "Failed to parse conversations "
611614
"record \"%.*s\" in %s: %s\n",
612-
(int)ca.keylen, ca.key,
615+
(int)ca.keybuf.len, ca.keybuf.s,
613616
a->path, error_message(r));
614617
/* There's no need to report failure to the caller - the
615618
* record diffing passing that occurs after this will
616619
* also pick up the same problem */
617620
goto next;
618621
}
619-
r = conversation_parsestatus(cb.data, cb.datalen, &statusb);
622+
r = conversation_parsestatus(cb.valbuf.s, cb.valbuf.len, &statusb);
620623
if (r) {
621624
fprintf(stderr, "Failed to parse conversations "
622625
"record \"%.*s\" in %s: %s\n",
623-
(int)cb.keylen, cb.key,
626+
(int)cb.keybuf.len, cb.keybuf.s,
624627
b->path, error_message(r));
625628
goto next;
626629
}
627630
if (statusa.threadmodseq > statusb.threadmodseq) {
628631
statusb.threadmodseq = statusa.threadmodseq;
629-
r = conversation_storestatus(b, cb.key, cb.keylen, &statusb);
632+
r = conversation_storestatus(b, cb.keybuf.s, cb.keybuf.len, &statusb);
630633
if (r) {
631634
fprintf(stderr, "Failed to store conversations "
632635
"record \"%.*s\" to %s: %s, giving up\n",
633-
(int)cb.keylen, cb.key,
636+
(int)cb.keybuf.len, cb.keybuf.s,
634637
b->path, error_message(r));
635638
/* If we cannot write to the temp DB, something is
636639
* drastically wrong and we need to report a failure */
637640
return r;
638641
}
639642
}
640643
}
641-
if (ca.key[0] == 'B') {
644+
if (ca.keybuf.s[0] == 'B') {
642645
/* B keys - check all the modseqs, both top level and per folder */
643646
conversation_t conva = CONVERSATION_INIT;
644647
conversation_t convb = CONVERSATION_INIT;
645648
conv_folder_t *foldera;
646649
conv_folder_t *folderb;
647650
conv_sender_t *sendera;
648651

649-
r = conversation_parse(ca.data, ca.datalen, &conva, CONV_WITHALL);
652+
r = conversation_parse(ca.valbuf.s, ca.valbuf.len, &conva, CONV_WITHALL);
650653
if (r) {
651654
fprintf(stderr, "Failed to parse conversations "
652655
"record \"%.*s\" in %s: %s\n",
653-
(int)ca.keylen, ca.key,
656+
(int)ca.keybuf.len, ca.keybuf.s,
654657
a->path, error_message(r));
655658
goto next;
656659
}
657-
r = conversation_parse(cb.data, cb.datalen, &convb, CONV_WITHALL);
660+
r = conversation_parse(cb.valbuf.s, cb.valbuf.len, &convb, CONV_WITHALL);
658661
if (r) {
659662
fprintf(stderr, "Failed to parse conversations "
660663
"record \"%.*s\" in %s: %s\n",
661-
(int)cb.keylen, cb.key,
664+
(int)cb.keybuf.len, cb.keybuf.s,
662665
b->path, error_message(r));
663666
conversation_fini(&conva);
664667
goto next;
@@ -688,7 +691,7 @@ static int fix_modseqs(struct conversations_state *a,
688691

689692
/* be nice to know if this is needed, but at least twoskip
690693
* will dedup for us */
691-
r = conversation_store(b, cb.key, cb.keylen, &convb);
694+
r = conversation_store(b, cb.keybuf.s, cb.keybuf.len, &convb);
692695

693696
/* free first before checking for errors */
694697
conversation_fini(&conva);
@@ -697,7 +700,7 @@ static int fix_modseqs(struct conversations_state *a,
697700
if (r) {
698701
fprintf(stderr, "Failed to store conversations "
699702
"record \"%.*s\" to %s: %s, giving up\n",
700-
(int)cb.keylen, cb.key,
703+
(int)cb.keybuf.len, cb.keybuf.s,
701704
b->path, error_message(r));
702705
return r;
703706
}

0 commit comments

Comments
 (0)