Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewriting strcasechr to compare multiple bytes at once #174

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 42 additions & 13 deletions src/match.c
Original file line number Diff line number Diff line change
@@ -1,19 +1,42 @@
#include <ctype.h>
#include <string.h>
#include <strings.h>
#include <stdio.h>
#include <float.h>
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include "match.h"
#include "bonus.h"

#include "../config.h"

char *strcasechr(const char *s, char c) {
const char accept[3] = {c, toupper(c), 0};
return strpbrk(s, accept);
typedef uint32_t long_t;
long_t *ws = NULL, w;
char u = toupper(c);
c = tolower(c);
if (c & 0x80) /* utf-8 bytes searched literally */
return strchr(s, c);
chr:
for (; ws || (uintptr_t)s % sizeof(long_t); s++) {
if (*s == '\0')
return NULL;
else if (*s == c)
return (char *)s;
else if (*s == u)
return (char *)s;
};
const long_t magic = (long_t) ~(-1ul / 0xff << 7);
const long_t cm = -1ul / 0xff * c;
const long_t um = -1ul / 0xff * u;
for (ws = (long_t *)s;; s = (char *)++ws) {
w = (*ws | (*ws & ~magic) / 2) & magic;
w = (w + magic) & ((w ^ cm) + magic) & ((w ^ um) + magic);
if (w ^ ~magic)
goto chr;
};
}

int has_match(const char *needle, const char *haystack) {
Expand All @@ -28,7 +51,12 @@ int has_match(const char *needle, const char *haystack) {
return 1;
}

#define SWAP(x, y, T) do { T SWAP = x; x = y; y = SWAP; } while (0)
#define SWAP(x, y, T) \
do { \
T SWAP = x; \
x = y; \
y = SWAP; \
} while (0)

#define max(a, b) (((a) > (b)) ? (a) : (b))

Expand All @@ -52,7 +80,8 @@ static void precompute_bonus(const char *haystack, score_t *match_bonus) {
}
}

static void setup_match_struct(struct match_struct *match, const char *needle, const char *haystack) {
static void setup_match_struct(struct match_struct *match, const char *needle,
const char *haystack) {
match->needle_len = strlen(needle);
match->haystack_len = strlen(haystack);

Expand All @@ -69,7 +98,8 @@ static void setup_match_struct(struct match_struct *match, const char *needle, c
precompute_bonus(haystack, match->match_bonus);
}

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) {
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) {
int n = match->needle_len;
int m = match->haystack_len;
int i = row;
Expand All @@ -87,11 +117,10 @@ static inline void match_row(const struct match_struct *match, int row, score_t
if (!i) {
score = (j * SCORE_GAP_LEADING) + match_bonus[j];
} else if (j) { /* i > 0 && j > 0*/
score = max(
last_M[j - 1] + match_bonus[j],
score = max(last_M[j - 1] + match_bonus[j],

/* consecutive match, doesn't stack with match_bonus */
last_D[j - 1] + SCORE_MATCH_CONSECUTIVE);
/* consecutive match, doesn't stack with match_bonus */
last_D[j - 1] + SCORE_MATCH_CONSECUTIVE);
}
curr_D[j] = score;
curr_M[j] = prev_score = max(score, prev_score + gap_score);
Expand Down Expand Up @@ -183,7 +212,7 @@ score_t match_positions(const char *needle, const char *haystack, size_t *positi
* D[][] Stores the best score for this position ending with a match.
* M[][] Stores the best possible score at this position.
*/
score_t (*D)[MATCH_MAX_LEN], (*M)[MATCH_MAX_LEN];
score_t(*D)[MATCH_MAX_LEN], (*M)[MATCH_MAX_LEN];
M = malloc(sizeof(score_t) * MATCH_MAX_LEN * n);
D = malloc(sizeof(score_t) * MATCH_MAX_LEN * n);

Expand Down