| ... | ... |
@@ -96,6 +96,39 @@ static void setup_match_struct(struct match_struct *match, const char *needle, c |
| 96 | 96 |
precompute_bonus(haystack, match->match_bonus); |
| 97 | 97 |
} |
| 98 | 98 |
|
| 99 |
+static inline void match_row(const struct match_struct *match, int row, score_t *curr_D, score_t *curr_M, const score_t *last_D, const score_t *last_M) {
|
|
| 100 |
+ int n = match->needle_len; |
|
| 101 |
+ int m = match->haystack_len; |
|
| 102 |
+ int i = row; |
|
| 103 |
+ |
|
| 104 |
+ const char *lower_needle = match->lower_needle; |
|
| 105 |
+ const char *lower_haystack = match->lower_haystack; |
|
| 106 |
+ const score_t *match_bonus = match->match_bonus; |
|
| 107 |
+ |
|
| 108 |
+ score_t prev_score = SCORE_MIN; |
|
| 109 |
+ score_t gap_score = i == n - 1 ? SCORE_GAP_TRAILING : SCORE_GAP_INNER; |
|
| 110 |
+ |
|
| 111 |
+ for (int j = 0; j < m; j++) {
|
|
| 112 |
+ if (lower_needle[i] == lower_haystack[j]) {
|
|
| 113 |
+ score_t score = SCORE_MIN; |
|
| 114 |
+ if (!i) {
|
|
| 115 |
+ score = (j * SCORE_GAP_LEADING) + match_bonus[j]; |
|
| 116 |
+ } else if (j) { /* i > 0 && j > 0*/
|
|
| 117 |
+ score = max( |
|
| 118 |
+ last_M[j - 1] + match_bonus[j], |
|
| 119 |
+ |
|
| 120 |
+ /* consecutive match, doesn't stack with match_bonus */ |
|
| 121 |
+ last_D[j - 1] + SCORE_MATCH_CONSECUTIVE); |
|
| 122 |
+ } |
|
| 123 |
+ curr_D[j] = score; |
|
| 124 |
+ curr_M[j] = prev_score = max(score, prev_score + gap_score); |
|
| 125 |
+ } else {
|
|
| 126 |
+ curr_D[j] = SCORE_MIN; |
|
| 127 |
+ curr_M[j] = prev_score = prev_score + gap_score; |
|
| 128 |
+ } |
|
| 129 |
+ } |
|
| 130 |
+} |
|
| 131 |
+ |
|
| 99 | 132 |
score_t match_positions(const char *needle, const char *haystack, size_t *positions) {
|
| 100 | 133 |
if (!*needle) |
| 101 | 134 |
return SCORE_MIN; |
| ... | ... |
@@ -124,10 +157,6 @@ score_t match_positions(const char *needle, const char *haystack, size_t *positi |
| 124 | 157 |
return SCORE_MAX; |
| 125 | 158 |
} |
| 126 | 159 |
|
| 127 |
- const char *lower_needle = match.lower_needle; |
|
| 128 |
- const char *lower_haystack = match.lower_haystack; |
|
| 129 |
- const score_t *match_bonus = match.match_bonus; |
|
| 130 |
- |
|
| 131 | 160 |
/* |
| 132 | 161 |
* D[][] Stores the best score for this position ending with a match. |
| 133 | 162 |
* M[][] Stores the best possible score at this position. |
| ... | ... |
@@ -138,31 +167,10 @@ score_t match_positions(const char *needle, const char *haystack, size_t *positi |
| 138 | 167 |
score_t *curr_D, *curr_M; |
| 139 | 168 |
|
| 140 | 169 |
for (int i = 0; i < n; i++) {
|
| 141 |
- score_t prev_score = SCORE_MIN; |
|
| 142 |
- score_t gap_score = i == n - 1 ? SCORE_GAP_TRAILING : SCORE_GAP_INNER; |
|
| 143 |
- |
|
| 144 | 170 |
curr_D = &D[i][0]; |
| 145 | 171 |
curr_M = &M[i][0]; |
| 146 | 172 |
|
| 147 |
- for (int j = 0; j < m; j++) {
|
|
| 148 |
- if (lower_needle[i] == lower_haystack[j]) {
|
|
| 149 |
- score_t score = SCORE_MIN; |
|
| 150 |
- if (!i) {
|
|
| 151 |
- score = (j * SCORE_GAP_LEADING) + match_bonus[j]; |
|
| 152 |
- } else if (j) { /* i > 0 && j > 0*/
|
|
| 153 |
- score = max( |
|
| 154 |
- last_M[j - 1] + match_bonus[j], |
|
| 155 |
- |
|
| 156 |
- /* consecutive match, doesn't stack with match_bonus */ |
|
| 157 |
- last_D[j - 1] + SCORE_MATCH_CONSECUTIVE); |
|
| 158 |
- } |
|
| 159 |
- curr_D[j] = score; |
|
| 160 |
- curr_M[j] = prev_score = max(score, prev_score + gap_score); |
|
| 161 |
- } else {
|
|
| 162 |
- curr_D[j] = SCORE_MIN; |
|
| 163 |
- curr_M[j] = prev_score = prev_score + gap_score; |
|
| 164 |
- } |
|
| 165 |
- } |
|
| 173 |
+ match_row(&match, i, curr_D, curr_M, last_D, last_M); |
|
| 166 | 174 |
|
| 167 | 175 |
last_D = curr_D; |
| 168 | 176 |
last_M = curr_M; |