Browse code

Reduce memory and avoid VLA in match()

When we're matching without recording positions, we only need to keep
two rows in memory at a time.

John Hawthorn authored on 28/12/2019 02:39:01
Showing 1 changed files

... ...
@@ -28,6 +28,8 @@ int has_match(const char *needle, const char *haystack) {
28 28
 	return 1;
29 29
 }
30 30
 
31
+#define SWAP(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)
32
+
31 33
 #define max(a, b) (((a) > (b)) ? (a) : (b))
32 34
 
33 35
 #ifdef DEBUG_VERBOSE
... ...
@@ -159,22 +161,24 @@ score_t match(const char *needle, const char *haystack) {
159 161
 	 * D[][] Stores the best score for this position ending with a match.
160 162
 	 * M[][] Stores the best possible score at this position.
161 163
 	 */
162
-	score_t D[n][m], M[n][m];
164
+	score_t D[2][MATCH_MAX_LEN], M[2][MATCH_MAX_LEN];
163 165
 
164 166
 	score_t *last_D, *last_M;
165 167
 	score_t *curr_D, *curr_M;
166 168
 
167
-	for (int i = 0; i < n; i++) {
168
-		curr_D = &D[i][0];
169
-		curr_M = &M[i][0];
169
+	last_D = D[0];
170
+	last_M = M[0];
171
+	curr_D = D[1];
172
+	curr_M = M[1];
170 173
 
174
+	for (int i = 0; i < n; i++) {
171 175
 		match_row(&match, i, curr_D, curr_M, last_D, last_M);
172 176
 
173
-		last_D = curr_D;
174
-		last_M = curr_M;
177
+		SWAP(curr_D, last_D, score_t *);
178
+		SWAP(curr_M, last_M, score_t *);
175 179
 	}
176 180
 
177
-	return M[n - 1][m - 1];
181
+	return last_M[m - 1];
178 182
 }
179 183
 
180 184
 score_t match_positions(const char *needle, const char *haystack, size_t *positions) {