@@ -448,8 +448,8 @@ struct cursor
448
448
{
449
449
struct db * db ;
450
450
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 ;
453
453
int err ;
454
454
};
455
455
@@ -463,24 +463,22 @@ static void cursor_init(struct cursor *c,
463
463
464
464
static int cursor_next (struct cursor * c )
465
465
{
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 ;
467
471
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 ,
471
475
c -> txnp );
476
+ buf_setmap (& c -> keybuf , key , keylen );
477
+ buf_setmap (& c -> valbuf , val , vallen );
478
+ }
472
479
return c -> err ;
473
480
}
474
481
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
-
484
482
static int next_diffable_record (struct cursor * c )
485
483
{
486
484
for (;;)
@@ -490,11 +488,11 @@ static int next_diffable_record(struct cursor *c)
490
488
491
489
/* skip < records, they won't be in the
492
490
* temp database and we don't care so much */
493
- if (c -> key [0 ] == '<' )
491
+ if (c -> keybuf . s [0 ] == '<' )
494
492
continue ;
495
493
496
494
/* Subject, not re-calculated */
497
- if (c -> key [0 ] == 'S' )
495
+ if (c -> keybuf . s [0 ] == 'S' )
498
496
continue ;
499
497
500
498
return 0 ;
@@ -517,13 +515,13 @@ static unsigned int diff_records(struct conversations_state *a,
517
515
rb = cursor_next (& cb );
518
516
519
517
while (!ra || !rb ) {
520
- keydelta = blob_compare ( ca .key , ca . keylen , cb .key , cb . keylen );
518
+ keydelta = buf_cmp ( & ca .keybuf , & cb .keybuf );
521
519
if (rb || keydelta < 0 ) {
522
520
if (ra ) break ;
523
521
ndiffs ++ ;
524
522
if (verbose )
525
523
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 );
527
525
ra = next_diffable_record (& ca );
528
526
continue ;
529
527
}
@@ -532,26 +530,31 @@ static unsigned int diff_records(struct conversations_state *a,
532
530
ndiffs ++ ;
533
531
if (verbose )
534
532
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 );
536
534
rb = next_diffable_record (& cb );
537
535
continue ;
538
536
}
539
537
540
538
/* 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 );
542
540
if (delta ) {
543
541
ndiffs ++ ;
544
542
if (verbose )
545
543
printf ("REAL: \"%.*s\" data \"%.*s\"\n"
546
544
"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 );
549
547
}
550
548
551
549
ra = next_diffable_record (& ca );
552
550
rb = next_diffable_record (& cb );
553
551
}
554
552
553
+ buf_free (& ca .keybuf );
554
+ buf_free (& ca .valbuf );
555
+ buf_free (& cb .keybuf );
556
+ buf_free (& cb .valbuf );
557
+
555
558
return ndiffs ;
556
559
}
557
560
@@ -570,20 +573,20 @@ static int fix_modseqs(struct conversations_state *a,
570
573
rb = cursor_next (& cb );
571
574
572
575
while (!ra || !rb ) {
573
- keydelta = blob_compare ( ca .key , ca . keylen , cb .key , cb . keylen );
576
+ keydelta = buf_cmp ( & ca .keybuf , & cb .keybuf );
574
577
if (rb || keydelta < 0 ) {
575
578
if (ra ) break ;
576
- if (ca .key [0 ] == 'F' ) {
579
+ if (ca .keybuf . s [0 ] == 'F' ) {
577
580
conv_status_t status = CONV_STATUS_INIT ;
578
581
/* 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 );
580
583
if (r ) return r ;
581
584
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 );
583
586
if (r ) {
584
587
fprintf (stderr , "Failed to store conversations "
585
588
"record \"%.*s\" to %s: %s, giving up\n" ,
586
- (int )ca .keylen , ca .key ,
589
+ (int )ca .keybuf . len , ca .keybuf . s ,
587
590
b -> path , error_message (r ));
588
591
return r ;
589
592
}
@@ -600,65 +603,65 @@ static int fix_modseqs(struct conversations_state *a,
600
603
}
601
604
602
605
/* folders? Just modseq check */
603
- if (ca .key [0 ] == 'F' ) {
606
+ if (ca .keybuf . s [0 ] == 'F' ) {
604
607
/* check if modseq is higher for real */
605
608
conv_status_t statusa = CONV_STATUS_INIT ;
606
609
conv_status_t statusb = CONV_STATUS_INIT ;
607
610
/* 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 );
609
612
if (r ) {
610
613
fprintf (stderr , "Failed to parse conversations "
611
614
"record \"%.*s\" in %s: %s\n" ,
612
- (int )ca .keylen , ca .key ,
615
+ (int )ca .keybuf . len , ca .keybuf . s ,
613
616
a -> path , error_message (r ));
614
617
/* There's no need to report failure to the caller - the
615
618
* record diffing passing that occurs after this will
616
619
* also pick up the same problem */
617
620
goto next ;
618
621
}
619
- r = conversation_parsestatus (cb .data , cb .datalen , & statusb );
622
+ r = conversation_parsestatus (cb .valbuf . s , cb .valbuf . len , & statusb );
620
623
if (r ) {
621
624
fprintf (stderr , "Failed to parse conversations "
622
625
"record \"%.*s\" in %s: %s\n" ,
623
- (int )cb .keylen , cb .key ,
626
+ (int )cb .keybuf . len , cb .keybuf . s ,
624
627
b -> path , error_message (r ));
625
628
goto next ;
626
629
}
627
630
if (statusa .threadmodseq > statusb .threadmodseq ) {
628
631
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 );
630
633
if (r ) {
631
634
fprintf (stderr , "Failed to store conversations "
632
635
"record \"%.*s\" to %s: %s, giving up\n" ,
633
- (int )cb .keylen , cb .key ,
636
+ (int )cb .keybuf . len , cb .keybuf . s ,
634
637
b -> path , error_message (r ));
635
638
/* If we cannot write to the temp DB, something is
636
639
* drastically wrong and we need to report a failure */
637
640
return r ;
638
641
}
639
642
}
640
643
}
641
- if (ca .key [0 ] == 'B' ) {
644
+ if (ca .keybuf . s [0 ] == 'B' ) {
642
645
/* B keys - check all the modseqs, both top level and per folder */
643
646
conversation_t conva = CONVERSATION_INIT ;
644
647
conversation_t convb = CONVERSATION_INIT ;
645
648
conv_folder_t * foldera ;
646
649
conv_folder_t * folderb ;
647
650
conv_sender_t * sendera ;
648
651
649
- r = conversation_parse (ca .data , ca .datalen , & conva , CONV_WITHALL );
652
+ r = conversation_parse (ca .valbuf . s , ca .valbuf . len , & conva , CONV_WITHALL );
650
653
if (r ) {
651
654
fprintf (stderr , "Failed to parse conversations "
652
655
"record \"%.*s\" in %s: %s\n" ,
653
- (int )ca .keylen , ca .key ,
656
+ (int )ca .keybuf . len , ca .keybuf . s ,
654
657
a -> path , error_message (r ));
655
658
goto next ;
656
659
}
657
- r = conversation_parse (cb .data , cb .datalen , & convb , CONV_WITHALL );
660
+ r = conversation_parse (cb .valbuf . s , cb .valbuf . len , & convb , CONV_WITHALL );
658
661
if (r ) {
659
662
fprintf (stderr , "Failed to parse conversations "
660
663
"record \"%.*s\" in %s: %s\n" ,
661
- (int )cb .keylen , cb .key ,
664
+ (int )cb .keybuf . len , cb .keybuf . s ,
662
665
b -> path , error_message (r ));
663
666
conversation_fini (& conva );
664
667
goto next ;
@@ -688,7 +691,7 @@ static int fix_modseqs(struct conversations_state *a,
688
691
689
692
/* be nice to know if this is needed, but at least twoskip
690
693
* 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 );
692
695
693
696
/* free first before checking for errors */
694
697
conversation_fini (& conva );
@@ -697,7 +700,7 @@ static int fix_modseqs(struct conversations_state *a,
697
700
if (r ) {
698
701
fprintf (stderr , "Failed to store conversations "
699
702
"record \"%.*s\" to %s: %s, giving up\n" ,
700
- (int )cb .keylen , cb .key ,
703
+ (int )cb .keybuf . len , cb .keybuf . s ,
701
704
b -> path , error_message (r ));
702
705
return r ;
703
706
}
0 commit comments