Fossil SCM

Add the test-delta-analyze command.

drh 2015-07-15 21:05 trunk
Commit fd302a26118849db815f04bc494bbe3bbd197029
2 files changed +61 +47 -4
+61
--- src/delta.c
+++ src/delta.c
@@ -589,10 +589,71 @@
589589
/* ERROR: generated size does not match predicted size */
590590
return -1;
591591
}
592592
return total;
593593
}
594
+ default: {
595
+ /* ERROR: unknown delta operator */
596
+ return -1;
597
+ }
598
+ }
599
+ }
600
+ /* ERROR: unterminated delta */
601
+ return -1;
602
+}
603
+
604
+/*
605
+** Analyze a delta. Figure out the total number of bytes copied from
606
+** source to target, and the total number of bytes inserted by the delta,
607
+** and return both numbers.
608
+*/
609
+int delta_analyze(
610
+ const char *zDelta, /* Delta to apply to the pattern */
611
+ int lenDelta, /* Length of the delta */
612
+ int *pnCopy, /* OUT: Number of bytes copied */
613
+ int *pnInsert /* OUT: Number of bytes inserted */
614
+){
615
+ unsigned int nInsert = 0;
616
+ unsigned int nCopy = 0;
617
+
618
+ (void)getInt(&zDelta, &lenDelta);
619
+ if( *zDelta!='\n' ){
620
+ /* ERROR: size integer not terminated by "\n" */
621
+ return -1;
622
+ }
623
+ zDelta++; lenDelta--;
624
+ while( *zDelta && lenDelta>0 ){
625
+ unsigned int cnt, ofst;
626
+ cnt = getInt(&zDelta, &lenDelta);
627
+ switch( zDelta[0] ){
628
+ case '@': {
629
+ zDelta++; lenDelta--;
630
+ ofst = getInt(&zDelta, &lenDelta);
631
+ if( lenDelta>0 && zDelta[0]!=',' ){
632
+ /* ERROR: copy command not terminated by ',' */
633
+ return -1;
634
+ }
635
+ zDelta++; lenDelta--;
636
+ nCopy += cnt;
637
+ break;
638
+ }
639
+ case ':': {
640
+ zDelta++; lenDelta--;
641
+ nInsert += cnt;
642
+ if( cnt>lenDelta ){
643
+ /* ERROR: insert count exceeds size of delta */
644
+ return -1;
645
+ }
646
+ zDelta += cnt;
647
+ lenDelta -= cnt;
648
+ break;
649
+ }
650
+ case ';': {
651
+ *pnCopy = nCopy;
652
+ *pnInsert = nInsert;
653
+ return 0;
654
+ }
594655
default: {
595656
/* ERROR: unknown delta operator */
596657
return -1;
597658
}
598659
}
599660
--- src/delta.c
+++ src/delta.c
@@ -589,10 +589,71 @@
589 /* ERROR: generated size does not match predicted size */
590 return -1;
591 }
592 return total;
593 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
594 default: {
595 /* ERROR: unknown delta operator */
596 return -1;
597 }
598 }
599
--- src/delta.c
+++ src/delta.c
@@ -589,10 +589,71 @@
589 /* ERROR: generated size does not match predicted size */
590 return -1;
591 }
592 return total;
593 }
594 default: {
595 /* ERROR: unknown delta operator */
596 return -1;
597 }
598 }
599 }
600 /* ERROR: unterminated delta */
601 return -1;
602 }
603
604 /*
605 ** Analyze a delta. Figure out the total number of bytes copied from
606 ** source to target, and the total number of bytes inserted by the delta,
607 ** and return both numbers.
608 */
609 int delta_analyze(
610 const char *zDelta, /* Delta to apply to the pattern */
611 int lenDelta, /* Length of the delta */
612 int *pnCopy, /* OUT: Number of bytes copied */
613 int *pnInsert /* OUT: Number of bytes inserted */
614 ){
615 unsigned int nInsert = 0;
616 unsigned int nCopy = 0;
617
618 (void)getInt(&zDelta, &lenDelta);
619 if( *zDelta!='\n' ){
620 /* ERROR: size integer not terminated by "\n" */
621 return -1;
622 }
623 zDelta++; lenDelta--;
624 while( *zDelta && lenDelta>0 ){
625 unsigned int cnt, ofst;
626 cnt = getInt(&zDelta, &lenDelta);
627 switch( zDelta[0] ){
628 case '@': {
629 zDelta++; lenDelta--;
630 ofst = getInt(&zDelta, &lenDelta);
631 if( lenDelta>0 && zDelta[0]!=',' ){
632 /* ERROR: copy command not terminated by ',' */
633 return -1;
634 }
635 zDelta++; lenDelta--;
636 nCopy += cnt;
637 break;
638 }
639 case ':': {
640 zDelta++; lenDelta--;
641 nInsert += cnt;
642 if( cnt>lenDelta ){
643 /* ERROR: insert count exceeds size of delta */
644 return -1;
645 }
646 zDelta += cnt;
647 lenDelta -= cnt;
648 break;
649 }
650 case ';': {
651 *pnCopy = nCopy;
652 *pnInsert = nInsert;
653 return 0;
654 }
655 default: {
656 /* ERROR: unknown delta operator */
657 return -1;
658 }
659 }
660
+47 -4
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -43,12 +43,14 @@
4343
}
4444
4545
/*
4646
** COMMAND: test-delta-create
4747
**
48
-** Given two input files, create and output a delta that carries
49
-** the first file into the second.
48
+** Usage: %fossil test-delta-create FILE1 FILE2 DELTA
49
+**
50
+** Create and output a delta that carries FILE1 into FILE2.
51
+** Store the result in DELTA.
5052
*/
5153
void delta_create_cmd(void){
5254
Blob orig, target, delta;
5355
if( g.argc!=5 ){
5456
usage("ORIGIN TARGET DELTA");
@@ -65,10 +67,47 @@
6567
}
6668
blob_reset(&orig);
6769
blob_reset(&target);
6870
blob_reset(&delta);
6971
}
72
+
73
+/*
74
+** COMMAND: test-delta-analyze
75
+**
76
+** Usage: %fossil test-delta-analyze FILE1 FILE2
77
+**
78
+** Create and a delta that carries FILE1 into FILE2. Print the
79
+** number bytes copied and the number of bytes inserted.
80
+*/
81
+void delta_analyze_cmd(void){
82
+ Blob orig, target, delta;
83
+ int nCopy = 0;
84
+ int nInsert = 0;
85
+ int sz1, sz2;
86
+ if( g.argc!=4 ){
87
+ usage("ORIGIN TARGET");
88
+ }
89
+ if( blob_read_from_file(&orig, g.argv[2])<0 ){
90
+ fossil_fatal("cannot read %s\n", g.argv[2]);
91
+ }
92
+ if( blob_read_from_file(&target, g.argv[3])<0 ){
93
+ fossil_fatal("cannot read %s\n", g.argv[3]);
94
+ }
95
+ blob_delta_create(&orig, &target, &delta);
96
+ delta_analyze(blob_buffer(&delta), blob_size(&delta), &nCopy, &nInsert);
97
+ sz1 = blob_size(&orig);
98
+ sz2 = blob_size(&target);
99
+ blob_reset(&orig);
100
+ blob_reset(&target);
101
+ blob_reset(&delta);
102
+ fossil_print("original size: %8d\n", sz1);
103
+ fossil_print("bytes copied: %8d (%.1f%% of target)\n",
104
+ nCopy, (100.0*nCopy)/sz2);
105
+ fossil_print("bytes inserted: %8d (%.1f%% of target)\n",
106
+ nInsert, (100.0*nInsert)/sz2);
107
+ fossil_print("final size: %8d\n", sz2);
108
+}
70109
71110
/*
72111
** Apply the delta in pDelta to the original file pOriginal to generate
73112
** the target file pTarget. The pTarget blob is initialized by this
74113
** routine.
@@ -102,12 +141,13 @@
102141
}
103142
104143
/*
105144
** COMMAND: test-delta-apply
106145
**
107
-** Given an input files and a delta, apply the delta to the input file
108
-** and write the result.
146
+** Usage: %fossil test-delta-apply FILE1 DELTA
147
+**
148
+** Apply DELTA to FILE1 and output the result.
109149
*/
110150
void delta_apply_cmd(void){
111151
Blob orig, target, delta;
112152
if( g.argc!=5 ){
113153
usage("ORIGIN DELTA TARGET");
@@ -124,13 +164,16 @@
124164
}
125165
blob_reset(&orig);
126166
blob_reset(&target);
127167
blob_reset(&delta);
128168
}
169
+
129170
130171
/*
131172
** COMMAND: test-delta
173
+**
174
+** Usage: %fossil test-delta FILE1 FILE2
132175
**
133176
** Read two files named on the command-line. Create and apply deltas
134177
** going in both directions. Verify that the original files are
135178
** correctly recovered.
136179
*/
137180
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -43,12 +43,14 @@
43 }
44
45 /*
46 ** COMMAND: test-delta-create
47 **
48 ** Given two input files, create and output a delta that carries
49 ** the first file into the second.
 
 
50 */
51 void delta_create_cmd(void){
52 Blob orig, target, delta;
53 if( g.argc!=5 ){
54 usage("ORIGIN TARGET DELTA");
@@ -65,10 +67,47 @@
65 }
66 blob_reset(&orig);
67 blob_reset(&target);
68 blob_reset(&delta);
69 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
71 /*
72 ** Apply the delta in pDelta to the original file pOriginal to generate
73 ** the target file pTarget. The pTarget blob is initialized by this
74 ** routine.
@@ -102,12 +141,13 @@
102 }
103
104 /*
105 ** COMMAND: test-delta-apply
106 **
107 ** Given an input files and a delta, apply the delta to the input file
108 ** and write the result.
 
109 */
110 void delta_apply_cmd(void){
111 Blob orig, target, delta;
112 if( g.argc!=5 ){
113 usage("ORIGIN DELTA TARGET");
@@ -124,13 +164,16 @@
124 }
125 blob_reset(&orig);
126 blob_reset(&target);
127 blob_reset(&delta);
128 }
 
129
130 /*
131 ** COMMAND: test-delta
 
 
132 **
133 ** Read two files named on the command-line. Create and apply deltas
134 ** going in both directions. Verify that the original files are
135 ** correctly recovered.
136 */
137
--- src/deltacmd.c
+++ src/deltacmd.c
@@ -43,12 +43,14 @@
43 }
44
45 /*
46 ** COMMAND: test-delta-create
47 **
48 ** Usage: %fossil test-delta-create FILE1 FILE2 DELTA
49 **
50 ** Create and output a delta that carries FILE1 into FILE2.
51 ** Store the result in DELTA.
52 */
53 void delta_create_cmd(void){
54 Blob orig, target, delta;
55 if( g.argc!=5 ){
56 usage("ORIGIN TARGET DELTA");
@@ -65,10 +67,47 @@
67 }
68 blob_reset(&orig);
69 blob_reset(&target);
70 blob_reset(&delta);
71 }
72
73 /*
74 ** COMMAND: test-delta-analyze
75 **
76 ** Usage: %fossil test-delta-analyze FILE1 FILE2
77 **
78 ** Create and a delta that carries FILE1 into FILE2. Print the
79 ** number bytes copied and the number of bytes inserted.
80 */
81 void delta_analyze_cmd(void){
82 Blob orig, target, delta;
83 int nCopy = 0;
84 int nInsert = 0;
85 int sz1, sz2;
86 if( g.argc!=4 ){
87 usage("ORIGIN TARGET");
88 }
89 if( blob_read_from_file(&orig, g.argv[2])<0 ){
90 fossil_fatal("cannot read %s\n", g.argv[2]);
91 }
92 if( blob_read_from_file(&target, g.argv[3])<0 ){
93 fossil_fatal("cannot read %s\n", g.argv[3]);
94 }
95 blob_delta_create(&orig, &target, &delta);
96 delta_analyze(blob_buffer(&delta), blob_size(&delta), &nCopy, &nInsert);
97 sz1 = blob_size(&orig);
98 sz2 = blob_size(&target);
99 blob_reset(&orig);
100 blob_reset(&target);
101 blob_reset(&delta);
102 fossil_print("original size: %8d\n", sz1);
103 fossil_print("bytes copied: %8d (%.1f%% of target)\n",
104 nCopy, (100.0*nCopy)/sz2);
105 fossil_print("bytes inserted: %8d (%.1f%% of target)\n",
106 nInsert, (100.0*nInsert)/sz2);
107 fossil_print("final size: %8d\n", sz2);
108 }
109
110 /*
111 ** Apply the delta in pDelta to the original file pOriginal to generate
112 ** the target file pTarget. The pTarget blob is initialized by this
113 ** routine.
@@ -102,12 +141,13 @@
141 }
142
143 /*
144 ** COMMAND: test-delta-apply
145 **
146 ** Usage: %fossil test-delta-apply FILE1 DELTA
147 **
148 ** Apply DELTA to FILE1 and output the result.
149 */
150 void delta_apply_cmd(void){
151 Blob orig, target, delta;
152 if( g.argc!=5 ){
153 usage("ORIGIN DELTA TARGET");
@@ -124,13 +164,16 @@
164 }
165 blob_reset(&orig);
166 blob_reset(&target);
167 blob_reset(&delta);
168 }
169
170
171 /*
172 ** COMMAND: test-delta
173 **
174 ** Usage: %fossil test-delta FILE1 FILE2
175 **
176 ** Read two files named on the command-line. Create and apply deltas
177 ** going in both directions. Verify that the original files are
178 ** correctly recovered.
179 */
180

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button