mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-06-23 15:30:45 -04:00
Use a 2D array for memoization, gives clearer code
This commit is contained in:
parent
ed45f1a6aa
commit
4398dda15f
@ -37,7 +37,7 @@ typedef struct {
|
|||||||
UChar *needle;
|
UChar *needle;
|
||||||
int32_t needle_len;
|
int32_t needle_len;
|
||||||
double max_score_per_char;
|
double max_score_per_char;
|
||||||
double *memo;
|
double **memo;
|
||||||
UChar *level1;
|
UChar *level1;
|
||||||
UChar *level2;
|
UChar *level2;
|
||||||
UChar *level3;
|
UChar *level3;
|
||||||
@ -58,7 +58,7 @@ static double recursive_match(MatchInfo *m, int32_t haystack_idx, int32_t needle
|
|||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
// do we have a memoized result we can return?
|
// do we have a memoized result we can return?
|
||||||
memoized = m->memo[needle_idx * m->needle_len + haystack_idx];
|
memoized = m->memo[needle_idx][haystack_idx];
|
||||||
if (memoized != DBL_MAX)
|
if (memoized != DBL_MAX)
|
||||||
return memoized;
|
return memoized;
|
||||||
|
|
||||||
@ -125,15 +125,29 @@ static double recursive_match(MatchInfo *m, int32_t haystack_idx, int32_t needle
|
|||||||
score = score > seen_score ? score : seen_score;
|
score = score > seen_score ? score : seen_score;
|
||||||
|
|
||||||
memoize:
|
memoize:
|
||||||
m->memo[needle_idx * m->needle_len + haystack_idx] = score;
|
m->memo[needle_idx][haystack_idx] = score;
|
||||||
return score;
|
return score;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static double** alloc_memo(size_t rows, size_t cols) {
|
||||||
|
double **array, *data; /* Declare this first so we can use it with sizeof. */
|
||||||
|
size_t i;
|
||||||
|
const size_t row_pointers_bytes = rows * sizeof(*array);
|
||||||
|
const size_t row_elements_bytes = cols * sizeof(**array);
|
||||||
|
array = malloc(row_pointers_bytes + rows * row_elements_bytes);
|
||||||
|
if (array != NULL) {
|
||||||
|
data = (double*)(array + rows);
|
||||||
|
for(i = 0; i < rows; i++) array[i] = data + i * cols;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
static bool match(UChar **items, int32_t *item_lengths, uint32_t item_count, UChar *needle, int32_t needle_len, Match *match_results, UChar *level1, UChar *level2, UChar *level3) {
|
static bool match(UChar **items, int32_t *item_lengths, uint32_t item_count, UChar *needle, int32_t needle_len, Match *match_results, UChar *level1, UChar *level2, UChar *level3) {
|
||||||
uint32_t i = 0, maxhl = 0, n = 0;
|
uint32_t i = 0, maxhl = 0;
|
||||||
|
int32_t r = 0, c = 0;
|
||||||
MatchInfo *matches = NULL;
|
MatchInfo *matches = NULL;
|
||||||
bool ok = FALSE;
|
bool ok = FALSE;
|
||||||
double *memo = NULL;
|
double **memo = NULL;
|
||||||
|
|
||||||
if (needle_len == 0) {
|
if (needle_len == 0) {
|
||||||
for (i = 0; i < item_count; i++) match_results[i].score = 0.0;
|
for (i = 0; i < item_count; i++) match_results[i].score = 0.0;
|
||||||
@ -155,13 +169,14 @@ static bool match(UChar **items, int32_t *item_lengths, uint32_t item_count, UCh
|
|||||||
matches[i].level3 = level3;
|
matches[i].level3 = level3;
|
||||||
maxhl = MAX(maxhl, matches[i].haystack_len);
|
maxhl = MAX(maxhl, matches[i].haystack_len);
|
||||||
}
|
}
|
||||||
maxhl *= needle_len;
|
|
||||||
|
|
||||||
memo = (double*)calloc(maxhl, sizeof(double));
|
memo = alloc_memo(needle_len, maxhl);
|
||||||
if (memo == NULL) goto end;
|
if (memo == NULL) {PyErr_NoMemory(); goto end;}
|
||||||
|
|
||||||
for (i = 0; i < item_count; i++) {
|
for (i = 0; i < item_count; i++) {
|
||||||
for (n = 0; n < maxhl; n++) memo[n] = DBL_MAX;
|
for (r = 0; r < needle_len; r++) {
|
||||||
|
for (c = 0; c < maxhl; c++) memo[r][c] = DBL_MAX;
|
||||||
|
}
|
||||||
matches[i].memo = memo;
|
matches[i].memo = memo;
|
||||||
match_results[i].score = recursive_match(&matches[i], 0, 0, 0, 0.0);
|
match_results[i].score = recursive_match(&matches[i], 0, 0, 0, 0.0);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user