@@ -1043,13 +1043,15 @@
1043 1043 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
1044 1044 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** The return value is a buffer of unsigned characters, obtained from
1045 1045 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** fossil_malloc(). (The caller needs to free the return value using
1046 1046 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** fossil_free().) Entries in the returned array have values as follows:
1047 1047 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
1048 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** 1. Delete the next line of pLeft.
1049 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** 2. The next line of pLeft changes into the next line of pRight.
1050 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- ** 3. Insert the next line of pRight.
1048 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 1. Delete the next line of pLeft.
1049 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 2. Insert the next line of pRight.
1050 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** 3... The next line of pLeft changes into the next line of pRight.
1051 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
1052 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Values larger than three indicate better matches.
1051 1053 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
1052 1054 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** The length of the returned array will be just large enough to cause
1053 1055 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** all elements of pLeft and pRight to be consumed.
1054 1056 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
**
1055 1057 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** Algorithm: Wagner's minimum edit-distance algorithm, modified by
@@ -1064,15 +1066,17 @@
1064 1066 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
){
1065 1067 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int i, j, k; /* Loop counters */
1066 1068 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int *a; /* One row of the Wagner matrix */
1067 1069 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int *pToFree; /* Space that needs to be freed */
1068 1070 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
unsigned char *aM; /* Wagner result matrix */
1071 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int nMatch, iMatch; /* Number of matching lines and match score */
1072 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int mnLen; /* MIN(nLeft, nRight) */
1069 1073 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int aBuf[100]; /* Stack space for a[] if nRight not to big */
1070 1074 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1071 1075 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aM = fossil_malloc( (nLeft+1)*(nRight+1) );
1072 1076 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( nLeft==0 ){
1073 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- memset(aM, 3, nRight);
1077 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ memset(aM, 2, nRight);
1074 1078 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return aM;
1075 1079 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1076 1080 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( nRight==0 ){
1077 1081 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
memset(aM, 1, nLeft);
1078 1082 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return aM;
@@ -1079,11 +1083,11 @@
1079 1083 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1080 1084 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1081 1085 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* This algorithm is O(N**2). So if N is too big, bail out with a
1082 1086 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
** simple (but stupid and ugly) result that doesn't take too long. */
1083 1087 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( nLeft*nRight>100000 ){
1084 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- memset(aM, 3, nRight);
1088 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ memset(aM, 2, nRight);
1085 1089 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
memset(aM+nRight, 1, nLeft);
1086 1090 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return aM;
1087 1091 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1088 1092 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1089 1093 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( nRight < (sizeof(aBuf)/sizeof(aBuf[0]))-1 ){
@@ -1093,30 +1097,30 @@
1093 1097 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
a = pToFree = fossil_malloc( sizeof(a[0])*(nRight+1) );
1094 1098 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1095 1099 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1096 1100 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Compute the best alignment */
1097 1101 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
for(i=0; i<=nRight; i++){
1098 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- aM[i] = 3;
1102 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ aM[i] = 2;
1099 1103 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
a[i] = i*50;
1100 1104 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1101 1105 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aM[0] = 0;
1102 1106 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
for(j=1; j<=nLeft; j++){
1103 1107 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int p = a[0];
1104 1108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
a[0] = p+50;
1105 1109 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aM[j*(nRight+1)] = 1;
1106 1110 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
for(i=1; i<=nRight; i++){
1107 1111 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int m = a[i-1]+50;
1108 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- int d = 3;
1112 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ int d = 2;
1109 1113 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( m>a[i]+50 ){
1110 1114 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
m = a[i]+50;
1111 1115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
d = 1;
1112 1116 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1113 1117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
if( m>p ){
1114 1118 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
int score = match_dline(&aLeft[j-1], &aRight[i-1]);
1115 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( (score<66 || (i<j+1 && i>j-1)) && m>p+score ){
1119 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( (score<=63 || (i<j+1 && i>j-1)) && m>p+score ){
1116 1120 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
m = p+score;
1117 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- d = 2;
1121 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ d = 3 | score*4;
1118 1122 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1119 1123 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1120 1124 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
p = a[i];
1121 1125 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
a[i] = m;
1122 1126 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aM[j*(nRight+1)+i] = d;
@@ -1125,17 +1129,20 @@
1125 1129 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1126 1130 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Compute the lowest-cost path back through the matrix */
1127 1131 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
i = nRight;
1128 1132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
j = nLeft;
1129 1133 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
k = (nRight+1)*(nLeft+1)-1;
1134 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nMatch = iMatch = 0;
1130 1135 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
while( i+j>0 ){
1131 1136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
unsigned char c = aM[k--];
1132 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- if( c==2 ){
1137 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( c>=3 ){
1133 1138 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
assert( i>0 && j>0 );
1134 1139 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
i--;
1135 1140 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
j--;
1136 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }else if( c==3 ){
1141 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ nMatch++;
1142 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ iMatch += (c>>2);
1143 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if( c==2 ){
1137 1144 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
assert( i>0 );
1138 1145 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
i--;
1139 1146 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}else{
1140 1147 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
assert( j>0 );
1141 1148 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
j--;
@@ -1143,10 +1150,26 @@
1143 1150 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
aM[k] = aM[j*(nRight+1)+i];
1144 1151 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1145 1152 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
k++;
1146 1153 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
i = (nRight+1)*(nLeft+1) - k;
1147 1154 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
memmove(aM, &aM[k], i);
1155 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+
1156 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ /* If:
1157 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** (1) the alignment is more than 25% longer than the longest side, and
1158 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** (2) the average match cost exceeds 15
1159 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** Then this is probably an alignment that will be difficult for humans
1160 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** to read. So instead, just show all of the right side inserted followed
1161 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** by all of the left side deleted.
1162 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ **
1163 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** The coefficients for conditions (1) and (2) above are determined by
1164 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ ** experimentation.
1165 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ */
1166 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ mnLen = nLeft>nRight ? nLeft : nRight;
1167 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ if( i*4>mnLen*5 && (nMatch==0 || iMatch/nMatch>15) ){
1168 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ memset(aM, 2, nRight);
1169 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ memset(aM+nRight, 1, nLeft);
1170 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }
1148 1171 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
1149 1172 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
/* Return the result */
1150 1173 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
fossil_free(pToFree);
1151 1174 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
return aM;
1152 1175 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
@@ -1294,11 +1317,11 @@
1294 1317 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
}
1295 1318 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
blob_append(pOut, s.zLine, s.n);
1296 1319 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
assert( ma>0 );
1297 1320 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
ma--;
1298 1321 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
a++;
1299 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
- }else if( alignment[j]==2 ){
1322 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
+ }else if( alignment[j]>=3 ){
1300 1323 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
s.n = 0;
1301 1324 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
sbsWriteLineChange(&s, &A[a], a, &B[b], b);
1302 1325 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
blob_append(pOut, s.zLine, s.n);
1303 1326 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
assert( ma>0 && mb>0 );
1304 1327 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!
ma--;
1305 1328 { copied = false; pop = false }, 1000)" :class="copied && 'copied'">Copy link Copied!