这是几种字符串匹配的算法实现。其中有bm算法,bf算法,以及sse实现的改进算法。和glibc系统库比较,最终没有像想想那样sse最快,还是系统库的最快。
/
*
* My personal strstr() implementation that beats most other algorithms.
* Until someone tells me otherwise, I assume that this is the
* fastest implementation of strstr() in C.
* I deliberately chose not to comment it. You should have at least
* as much fun trying to understand it, as I had to write it :-).
*
* Stephen R. van den Berg, berg@pool.informatik.rwth-aachen.de */
#include "stdlib.h"
#include "stdio.h"
typedef unsigned chartype;
char *strstrBerg (const char *phaystack,const char *pneedle)
{
const unsigned char *haystack, *needle;
chartype b;
const unsigned char *rneedle;
haystack = (const unsigned char *) phaystack;
if ((b = *(needle = (const unsigned char *) pneedle)))
{
chartype c;
haystack--; /* possible ANSI violation */
{
chartype a;
do
if (!(a = *++haystack))
goto ret0;/* if haystack ends, return 0 */
while (a != b); /* find the first postion that equals */
}
/* first char equals, go on */
if (!(c = *++needle))
goto foundneedle; /* only one char in needle, found it */
++needle;/* needle go to 3rd char */
goto jin;
for (;;)
{
{
chartype a;
if (0)
jin:
{
if ((a = *++haystack) == c)/* check if the second char in needle equals*/
goto crest;
}
else
a = *++haystack;
do
{
for (; a != b; a = *++haystack)/* search haystack to find a char equals the 1st char of needle */
{
if (!a)
goto ret0;
if ((a = *++haystack) == b) /* one loop compare 2 chars */
break;
if (!a)
goto ret0;
}
}
while ((a = *++haystack) != c); /* until second char equals */
}
crest:/* 2 char equals, go on */
{
chartype a;
{
const unsigned char *rhaystack;
/* rhaystack =next char, haystack-- set haystack point at the postion to be returned */
if (*(rhaystack = haystack-- + 1) == (a = *(rneedle = needle)))/* go on comparing from 3rd char of needle */
do
{
if (!a)
goto foundneedle;
if (*++rhaystack != (a = *++needle))
break;
if (!a)
goto foundneedle;
}
while (*++rhaystack == (a = *++needle));/* until reach a char not equal */
needle = rneedle; /* took the register-poor aproach ,needle point to 3rd char */
}
if (!a)
break;
}
}
}
foundneedle:
return (char *) haystack;
ret0:
return 0;
}
/* String matching by maximal suffices. */
char* strstrToy(const char*haystack, const char*needle) {
size_t ul;
if (!*needle)
return (char*)haystack;
if (!needle[1])
return strchr(haystack, *needle);
/* Here follow some heuristics for finding a reasonable place to start
* the search, since this code is slower by a decently large constant factor
* than Stephen van den Berg's code in easy cases, particularly on short
* strings.
*/
{
size_t s;
/* use naive algorithm on short patterns. */
for (s = 2; s < 8; s++)
if (!needle[s])
return strstrBerg(haystack, needle);
/* find the first occurrence of needle as a subsequence of haystack. */
for (s = 0; needle[s]; s++) {
while (haystack[s] != needle[s] && haystack[s])
haystack++;
if (!haystack[s])
return NULL;
}
/* look for the first 7 chars of needle in haystack. */
char foo[8];
for (s = 0; s < 7; s++)
foo[s] = needle[s];
foo[7] = 0;
haystack = (const char*)strstrBerg(haystack, foo);
if (haystack == NULL)
return NULL;
}
const char *v;
/* find a maximal suffix of needle, and store it in v. */
{
size_t i, j = 0, p;
while (1) {
/* find the longest self-maximal prefix of needle[j...strlen(needle)].
* i is its end, and p is its period. */
for (i = j+1, p = 1; needle[i]; i++) {
if (needle[i] < needle[i - p])
p = i - j + 1;
else if (needle[i] > needle[i - p])
break;
}
/* needle[j...i-1] is the longest self-maximal prefix of needle+j. */
if (needle[i])
j = i - (i - j) % p;
else
break;
}
v = needle + j;
ul = j;
}
/* use Stephen's code for short v. */
if (strlen(v) < 10) {
const char *prev = haystack;
const char *hay = haystack + ul;
while (1) {
hay = strstrBerg(hay, v);
if (hay == NULL)
goto retnull;
if (hay - prev >= ul && !memcmp(hay - ul, needle, ul))
return (char*)(hay - ul);
prev = hay;
hay++;
}
}
/* now do the searching. */
{
size_t p = 1, j = 0;
const char *hi = haystack+ul;
const char *prev = haystack;
while (1) {
/* match pattern characters against text characters. */
while (v[j] == hi[j] && v[j]) {
/* The character v[j] breaks the periodicity of v.
* We therefore have the situation depicted in the following cartoon:
*
* /---p---\ j
* v: [a b c d|a b c d|a b c d|a b x.............]
*
* The period of this string is at least j, so we update p accordingly.
*
* Why can't it be less than j?
* Suppose that the period of v[0...j] were less than j, even though
* v[j] != v[j - p]. There are two cases:
* Case 1: v[j] > v[j - p]
* Then v[0...j] is less than v[p...j], since
* v[0...j-p-1] = v[p...j-1] while v[j] > v[j-p], a contradiction.
* Case 2: v[j] < v[j - p]
* Let q be the actual period of v[0...j].
* Then v[j % q] < v[j - p].
* Thus, v[j - p - (j % q)...j] > v[0...j], since
* v[j - p - (j % q)...j - p - 1] = v[0...(j % q) - 1]
* while v[j - p] > v[j] = v[j % q].
* This is again a contradiction.
*/
if (j > p && v[j] != v[j-p])
p = j;
j++;
}
if (!v[j]) { /* v matches. */
if (hi >= prev) {
if (!memcmp(hi-ul, needle, ul)) /* whole string matches. */
return (char*)(hi-ul);
/* u doesn't match. */
}
/* else, u cannot possibly match since v was a maximal suffix. */
prev = hi+ul; /* u doesn't match. set prev accordingly. */
}
else if (!hi[j])
goto retnull;
/* We know that v[0...j] has period p. We also know that j characters of
* the text match. We can therefore shift the pattern over by p, since at
* least the first p characters of haystack+i must match the first p
* characters of v.
*/
hi += p;
/* Similarly, if we matched the first 2p characters of v, we must match
* the first p characters of the needle against the first p characters of
* the haystack, so we shift v by p.
*/
if (j >= p+p) j -= p;
else p=1, j = 0;
}
}
retnull:
return NULL;
}
char* MYSQLstrstr(const char *str,const char *search)
{
char *i,*j;
char first= *search;
skip:
while (*str != '\0') {
if (*str++ == first) {
i=(char*)str; j=(char*) search+1;
while (*j)
if (*i++ != *j++)
goto skip;
/* return (str-1); */
return (char *)str-1;
}
}
return ((char*) 0);
} /** strstr */
char *strstr_fxxx (char *text, char *pattern)
{
char *p;
for (p = text; *p; p++)
{
char *pp = p, *t = pattern;
while (*pp == *t && *t)
pp++, t++;
if (!*t)
return p;
}
return NULL;
}
#define XSIZE 100
#define ASIZE 256
#define MAX(a,b) (a>b)?a:b
#define SRET(i) return NULL;
#define STOP 1
#define SEARCH_STOP 1
static int report_default(const char* text, int idx, const char* pat)
{
return SEARCH_STOP;
}
typedef int (*reportFunc)(const char* text, int idx, const char* pat);
reportFunc report_function = report_default;
/* #define OUTPUT(x) if( report_function(text, x, pat) == STOP ) return (text + (x)); */
void preBmBc(char *pat, int m, int bmBc[]) {
int i;
for (i = 0; i < ASIZE; ++i)
bmBc[i] = m;
for (i = 0; i < m - 1; ++i)
bmBc[pat[i]] = m - i - 1;
}
void suffipates(char *pat, int m, int *suff) {
int f, g, i;
suff[m - 1] = m;
g = m - 1;
for (i = m - 2; i >= 0; --i) {
if (i > g && suff[i + m - 1 - f] < i - g)
suff[i] = suff[i + m - 1 - f];
else {
if (i < g)
g = i;
f = i;
while (g >= 0 && pat[g] == pat[g + m - 1 - f])
--g;
suff[i] = f - g;
}
}
}
void preBmGs(char *pat, int m, int bmGs[]) {
int i, j, suff[XSIZE];
suffipates(pat, m, suff);
for (i = 0; i < m; ++i)
bmGs[i] = m;
j = 0;
for (i = m - 1; i >= -1; --i)
if (i == -1 || suff[i] == i + 1)
for (; j < m - 1 - i; ++j)
if (bmGs[j] == m)
bmGs[j] = m - 1 - i;
for (i = 0; i <= m - 2; ++i)
bmGs[m - 1 - suff[i]] = m - 1 - i;
}
char* Sbm2(char *texts, char *pat,int n, int m) {
int i, j, bmGs[XSIZE], bmBc[ASIZE];
// printf("n lenth of bm:%d,m:%d,",n,m);
unsigned char* text= (unsigned char*) texts;
/* Preprocessing */
preBmGs(pat, m, bmGs);
preBmBc(pat, m, bmBc);
/* Searching */
j = 0;
while (j <= n - m) {
for (i = m - 1; (i >= 0) && (pat[i] == text[i + j]); --i);
if (i < 0) {
if( report_function(text, j, pat) == STOP )
return (text + (j));
j += bmGs[0];
}
else{
int skipn = MAX(bmGs[i], bmBc[text[i + j]] - m + 1 + i);
//if(skipn> m)
//printf("err\n");
j += skipn;
}
}
return NULL;
}
char* Sbm(char *text, char *pat) {
int m,n;
m=strlen(pat);
n=strlen(text);
return Sbm2(text,pat,n,m);
}
#include <emmintrin.h>
#include <xmmintrin.h>
#define USE_BTR
char* strchrsse(const char *str,char c);
char* strstrabsse(char* text, char* pattern);
//#define REPORT(i) return i;
#ifndef REPORT
#define REPORT(i) {if( report_function(text, i-text, pattern)== SEARCH_STOP) return i;};
#endif
static inline unsigned int hasByteC16(__m128i a0, register __m128i sseic)
{
return ((_mm_movemask_epi8(_mm_cmpeq_epi8(a0,sseic)) ) );
}
static inline unsigned int hasByteC(__m128i a0, __m128i a1, register __m128i sseic)
{
return ((_mm_movemask_epi8(_mm_cmpeq_epi8(a0,sseic)) ) | \
(_mm_movemask_epi8(_mm_cmpeq_epi8(a1,sseic)) << 16) \
);
}
#define haszeroByte hasByteC
inline static int strcmpInline(char* str1,char* str2)
{
while((*str2) && (*str1 == * str2)) {
str1++;
str2++;
}
if(*str2 == 0) return 0;
return 1;
}
# define bsf(x) __builtin_ctz(x)
char* strstrsse(const char* text, const char* pattern)
{
__m128i * sseiPtr = (__m128i *) text;
unsigned char * chPtrAligned = (unsigned char*)text;
__m128i sseiWord0 ;//= *sseiPtr ;
__m128i sseiWord1 ;//= *sseiPtr ;
__m128i sseiZero = _mm_set1_epi8(0);
char chara;
char charb;
char charc;
register __m128i byte16a;
register __m128i byte16b;
register __m128i byte16c;
char* bytePtr =text;
if(text==NULL)
return NULL;
if(text[0] == 0) {
return pattern[0]?NULL:text;
}
if(pattern ==NULL)
return NULL;
if(pattern[0] == 0)
return text;
if(pattern[1] == 0)
return strchrsse(text,pattern[0]);
if(pattern[2] == 0)
return strstrabsse(text,pattern);
chara = pattern[0];
charb = pattern[1];
charc = pattern[2];
byte16a = _mm_set1_epi8(chara);
byte16b = _mm_set1_epi8(charb);
byte16c = _mm_set1_epi8(charc);
#if 1
//! the pre-byte that is not aligned.
{
int i;
int j;
int preBytes = 16 - (((unsigned long long) text) & 15);
preBytes &= 15;
if (preBytes == 0)
goto alignStart;
chPtrAligned = (unsigned char*)text + preBytes;
for(j =0;j< preBytes; j++){
if(text[j] ==0)
return NULL;
if(text[j] == chara){
if(text[j+1] == charb){
int i=1;
bytePtr = & text[j];
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
}
}
sseiPtr = (__m128i *) chPtrAligned;
}
#endif
alignStart:
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0)
{
unsigned int reta ;
searcha:
reta = hasByteC(sseiWord0,sseiWord1, byte16a);
if(reta!=0 ) {
unsigned int retb ;
unsigned int retc ;
findouta:
retb = hasByteC(sseiWord0,sseiWord1, byte16b);
retc = hasByteC(sseiWord0,sseiWord1, byte16c);
findoutb:
reta = (reta ) & (retb >> 1);
reta = (reta ) & (retc >> 2);
if(reta)
{
// have ab
int i=1;
char * bytePtr0 = (char*) ( sseiPtr );
int j;
#ifdef USE_BTR
while(reta){
int idx ;
idx = bsf(reta);
bytePtr = bytePtr0 + idx ;
i = 3;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
//reta = reta & ( ~(1<<idx));
__asm__ ( "btr %1, %0"
:"=r"(reta)
:"r"(idx),"0"(reta)
);
}
#else
//search completely : version no bsf instruction
for(j =0;j<8;j++){
if(reta & 0xff) {
if(bytePtr0[0] == chara)
//if(reta & 1)
{
i =1;
bytePtr = bytePtr0 ;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
}
if(bytePtr0[1] == chara)
//if(reta & 2)
{
i =1;
bytePtr = bytePtr0 + 1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
}
if(bytePtr0[2] == chara)
//if(reta & 4)
{
i =1;
bytePtr = bytePtr0 + 2;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
}
if(bytePtr0[3] == chara)
//if(reta & 8)
{
i =1;
bytePtr = bytePtr0 + 3;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
}
}
reta = reta >> 4;
bytePtr0 += 4;
}
#endif
}
// search b
sseiPtr += 2;
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0){
retc = hasByteC(sseiWord0,sseiWord1, byte16c);
if(retc !=0){
//! this line will decrease the performance, I am a little amazed. if(retc& (3<<30))
{
if((*((char*) sseiPtr)) == charb){
//a|||b000
char * bytePtr = ((char*) ( sseiPtr )) -1;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
}
#if 1
if((*((char*) sseiPtr)) == charc){
//ab||||c000
char * bytePtr = ((char*) ( sseiPtr )) -2;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
}
}
#endif
reta = hasByteC(sseiWord0,sseiWord1, byte16a);
if(reta !=0)
{
retb = hasByteC(sseiWord0,sseiWord1, byte16b);
if(retb !=0)
goto findoutb;
else
{
if(*(char*) (sseiPtr +2) == charb ){
char * bytePtr = ((char*) ( sseiPtr +2 )) -1;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
}
goto nextWord;
}
}
else{
goto nextWord;
}
}
sseiPtr += 2;
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
}
// search from (char*)sseiPtr
char * bytePtr = ((char*) ( sseiPtr )) -1;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
}
bytePtr --;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
}
goto prePareForEnd;
}
nextWord:
sseiPtr += 2;
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
}
prePareForEnd:
{
unsigned int reta;
unsigned int retb;
reta =hasByteC(sseiWord0,sseiWord1, byte16a);
retb =hasByteC(sseiWord0,sseiWord1, byte16b);
if(((reta<<1) & retb)){
bytePtr = (char*)sseiPtr;
while(*bytePtr){
if(*bytePtr == chara) {
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
bytePtr++;
}
}
}
return NULL;
}
char* strstrabsse(char* text, char* pattern)
{
__m128i * sseiPtr = (__m128i *) text;
unsigned char * chPtrAligned = (unsigned char*)text;
__m128i sseiWord0 ;//= *sseiPtr ;
__m128i sseiWord1 ;//= *sseiPtr ;
__m128i sseiZero = _mm_set1_epi8(0);
char chara = pattern[0];
char charb = pattern[1];
register __m128i byte16a;
register __m128i byte16b;
char* bytePtr =text;
if(pattern ==NULL)
return NULL;
if(pattern[0] == 0)
return NULL;
if(pattern[1] == 0)
return strchrsse(text,pattern[0]);
byte16a = _mm_set1_epi8(chara);
byte16b = _mm_set1_epi8(charb);
#if 1
//! the pre-byte that is not aligned.
{
int i;
int j;
int preBytes = 16 - (((unsigned long long) text) & 15);
preBytes &= 15;
if (preBytes == 0)
goto alignStart;
chPtrAligned = (unsigned char*)text + preBytes;
for(j =0;j< preBytes; j++){
if(text[j] ==0)
return NULL;
if(text[j] == chara){
if(text[j+1] == charb){
int i=1;
bytePtr = & text[j];
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
}
}
sseiPtr = (__m128i *) chPtrAligned;
}
#endif
alignStart:
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0)
{
unsigned int reta ;
searcha:
reta = hasByteC(sseiWord0,sseiWord1, byte16a);
if(reta!=0 ) {
unsigned int retb ;
findouta:
retb = hasByteC(sseiWord0,sseiWord1, byte16b);
findoutb:
reta = (reta ) & (retb >> 1);
if(reta)
{
// have ab
int i=1;
char * bytePtr0 = (char*) ( sseiPtr );
int j;
//printf("test::%0x,%d\n",reta ,bytePtr0 -text);
bytePtr = (char*) ( sseiPtr );
for(j =0;j<8;j++){
if(reta & 0xff) {
//if(bytePtr0[0] == chara)
if(reta & 1)
{
bytePtr = bytePtr0 ;
REPORT(bytePtr);
}
//if(bytePtr0[1] == chara)
if(reta & 2)
{
bytePtr = bytePtr0 + 1;
REPORT(bytePtr);
}
//if(bytePtr0[2] == chara)
if(reta & 4)
{
bytePtr = bytePtr0 + 2;
REPORT(bytePtr);
}
//if(bytePtr0[3] == chara)
if(reta & 8)
{
bytePtr = bytePtr0 + 3;
REPORT(bytePtr);
}
}
reta = reta >> 4;
bytePtr0 += 4;
}
}
// search b
sseiPtr += 2;
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0){
retb = hasByteC(sseiWord0,sseiWord1, byte16b);
if(retb !=0){
// findout b
if((*((char*) sseiPtr)) == charb){
//b000
char * bytePtr = ((char*) ( sseiPtr )) -1;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
}
reta = hasByteC(sseiWord0,sseiWord1, byte16a);
if(reta !=0)
goto findoutb;
else{
goto nextWord;
}
}
sseiPtr += 2;
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
}
// search from (char*)sseiPtr
char * bytePtr = ((char*) ( sseiPtr )) -1;
if(bytePtr[0] == chara){
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++;
if(pattern[i] == 0) REPORT(bytePtr);
}
goto prePareForEnd;
}
nextWord:
sseiPtr += 2;
sseiWord0 = *sseiPtr;
sseiWord1 = *(sseiPtr+1);
}
prePareForEnd:
{
unsigned int reta;
unsigned int retb;
reta =hasByteC(sseiWord0,sseiWord1, byte16a);
retb =hasByteC(sseiWord0,sseiWord1, byte16b);
if(((reta<<1) & retb)){
bytePtr = (char*)sseiPtr;
while(*bytePtr){
if(*bytePtr == chara) {
int i=1;
while((pattern[i] )&&(bytePtr[i] == pattern[i]))
i++;
if(pattern[i] == 0)
REPORT(bytePtr);
if(bytePtr[i] == 0)
return NULL;
}
bytePtr++;
}
}
}
return NULL;
}
char* strchrsse(const char *text,char c)
{
const char *char_ptr=text;
const __m128i* m128_ptr;
char pattern[2] ={c,0};
__m128i byte16c= _mm_set1_epi8(c);
__m128i sseiZero = _mm_set1_epi8(0);
__m128i m128word;
for (char_ptr = text; ((unsigned int)char_ptr
& (sizeof(__m128) - 1)) != 0;
++char_ptr) {
if (*char_ptr == '\0')
return NULL;
if (*char_ptr == c)
REPORT(char_ptr);
}
m128_ptr = (__m128*)char_ptr;
m128word= *m128_ptr;
while ((hasByteC16(m128word, sseiZero))==0) {
if (hasByteC16(m128word, byte16c) != 0) {
int i;
const char *cp = (const char*)(m128_ptr);
//const char* endcp = cp + 16;
for(i=0;i<16;i++){
if(*cp == c)
REPORT(cp);
if(*cp==0)
return NULL;
cp++;
}
}
m128_ptr++;
m128word= *m128_ptr;
}
{
const char* cp = (const char*) m128_ptr;
while(*cp){
if(*cp == c) REPORT(cp);
cp++;
}
}
return NULL;
}
#define false 0
#define true 1
int Like(char *pattern, char escape_character)
{
char *p = pattern; // a short for pattern (or processed pattern)
char *w = pattern; // a short for wildcard map (or na original pattern, if no escape chars)
char *v = "aaaaadfdadsfasdfasdfasdfasdfasd"; // a short for the data itself
uint pattern_len = strlen(pattern);
int len = strlen(v);
// Escape characters processing
int i;
for( i = 0; i < pattern_len - 1; i++) {
if(p[i] == escape_character && (p[i + 1] == escape_character || p[i + 1] == '_' || p[i + 1] == '%')) {
break;
}
}
// Pattern processing
int was_wild = true; // are we in "after %" mode?
uint cur_p = 0, cur_p_beg = 0; // pattern positions
uint cur_s = 0, cur_s_beg = 0; // source positions
do {
while(cur_p < pattern_len && w[cur_p] == '%') { // first omit all %
was_wild = true;
cur_p++;
}
cur_s_beg = cur_s;
cur_p_beg = cur_p;
do { // internal loop: try to match a part between %...%
while(cur_p < pattern_len && cur_s < len && // find the first match...
(v[cur_s] == p[cur_p] || w[cur_p] == '_') &&
w[cur_p] != '%' ) {
cur_s++;
cur_p++;
}
if(cur_s < len && ((cur_p < pattern_len && w[cur_p] != '%') || cur_p >= pattern_len)) { // not matching (loop finished prematurely) - try the next source position
if(!was_wild)
return false; // no % up to now => the first non-matching is critical
cur_p = cur_p_beg;
cur_s = ++cur_s_beg; // step forward in the source, rewind the matching pointers
}
if(cur_s == len) { // end of the source
while(cur_p < pattern_len) {
if(w[cur_p] != '%') // Pattern nontrivial yet? No more chances for matching.
return false;
cur_p++;
}
return true;
}
} while(cur_p < pattern_len && w[cur_p] != '%'); // try the next match position
} while(cur_p < pattern_len && cur_s < len);
return true;
}
/* char* strstrabxsse(char* text, char* pattern) */
/* { */
/* __m128i * sseiPtr = (__m128i *) text; */
/* unsigned char * chPtrAligned = (unsigned char*)text; */
/* __m128i sseiWord0 ;//= *sseiPtr ; */
/* __m128i sseiWord1 ;//= *sseiPtr ; */
/* __m128i sseiZero = _mm_set1_epi8(0); */
/* char chara = pattern[0]; */
/* char charb = pattern[1]; */
/* register __m128i byte16a; */
/* register __m128i byte16b; */
/* char* bytePtr =text; */
/* if(pattern ==NULL) return NULL; */
/* if(pattern[0] == 0) return NULL; */
/* if(pattern[1] == 0) return strchrsse(text,pattern[0]); */
/* byte16a = _mm_set1_epi8(chara); */
/* byte16b = _mm_set1_epi8(charb); */
/* #if 1 */
/* //! the pre-byte that is not aligned. */
/* { */
/* int i; */
/* int j; */
/* int preBytes = 16 - (((unsigned long long) text) & 15); */
/* preBytes &= 15; */
/* if (preBytes == 0) */
/* goto alignStart; */
/* chPtrAligned = (unsigned char*)text + preBytes; */
/* for(j =0;j< preBytes; j++){ */
/* if(text[j] ==0) */
/* return NULL; */
/* if(text[j] == chara){ */
/* if(text[j+1] == charb){ */
/* int i=1; */
/* bytePtr = & text[j]; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/* i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* if(bytePtr[i] == 0) */
/* return NULL; */
/* } */
/* } */
/* } */
/* sseiPtr = (__m128i *) chPtrAligned; */
/* } */
/* #endif */
/* alignStart: */
/* sseiWord0 = *sseiPtr; */
/* sseiWord1 = *(sseiPtr+1); */
/* while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0) */
/* { */
/* unsigned int reta ; */
/* searcha: */
/* reta = hasByteC(sseiWord0,sseiWord1, byte16a); */
/* if(reta!=0 ) { */
/* unsigned int retb ; */
/* findouta: */
/* retb = hasByteC(sseiWord0,sseiWord1, byte16b); */
/* findoutb: */
/* reta = (reta ) & (retb >> 1); */
/* if(reta) */
/* { */
/* // have ab */
/* int i=1; */
/* char * bytePtr0 = (char*) ( sseiPtr ); */
/* int j; */
/* //printf("test::%0x,%d\n",reta ,bytePtr0 -text); */
/* bytePtr = (char*) ( sseiPtr ); */
/* for(j =0;j<8;j++){ */
/* if(reta & 0xff) { */
/* if(bytePtr0[0] == chara) */
/* //if(reta & 1) */
/* { */
/* i =1; */
/* bytePtr = bytePtr0 ; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/* i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* } */
/* if(bytePtr0[1] == chara) */
/* //if(reta & 2) */
/* { */
/* i =1; */
/* bytePtr = bytePtr0 + 1; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/* i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* } */
/* if(bytePtr0[2] == chara) */
/* //if(reta & 4) */
/* { */
/* i =1; */
/* bytePtr = bytePtr0 + 2; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++; */
/* if(pattern[i] == 0) REPORT(bytePtr); */
/* } */
/* if(bytePtr0[3] == chara) */
/* //if(reta & 8) */
/* { */
/* i =1; */
/* bytePtr = bytePtr0 + 3; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/* i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* } */
/* } */
/* reta = reta >> 4; */
/* bytePtr0 += 4; */
/* } */
/* } */
/* // search b */
/* sseiPtr += 2; */
/* sseiWord0 = *sseiPtr; */
/* sseiWord1 = *(sseiPtr+1); */
/* while( haszeroByte(sseiWord0,sseiWord1,sseiZero) ==0){ */
/* retb = hasByteC(sseiWord0,sseiWord1, byte16b); */
/* if(retb !=0){ */
/* // findout b */
/* if((*((char*) sseiPtr)) == charb){ */
/* //b000 */
/* char * bytePtr = ((char*) ( sseiPtr )) -1; */
/* if(bytePtr[0] == chara){ */
/* int i=1; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* if(bytePtr[i] == 0) */
/* return NULL; */
/* } */
/* } */
/* reta = hasByteC(sseiWord0,sseiWord1, byte16a); */
/* if(reta !=0) */
/* goto findoutb; */
/* else{ */
/* goto nextWord; */
/* } */
/* } */
/* sseiPtr += 2; */
/* sseiWord0 = *sseiPtr; */
/* sseiWord1 = *(sseiPtr+1); */
/* } */
/* // search from (char*)sseiPtr */
/* char * bytePtr = ((char*) ( sseiPtr )) -1; */
/* if(bytePtr[0] == chara){ */
/* int i=1; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) */
/* i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* } */
/* goto prePareForEnd; */
/* } */
/* nextWord: */
/* sseiPtr += 2; */
/* sseiWord0 = *sseiPtr; */
/* sseiWord1 = *(sseiPtr+1); */
/* } */
/* prePareForEnd: */
/* { */
/* unsigned int reta; */
/* unsigned int retb; */
/* reta =hasByteC(sseiWord0,sseiWord1, byte16a); */
/* retb =hasByteC(sseiWord0,sseiWord1, byte16b); */
/* if(((reta<<1) & retb)){ */
/* bytePtr = (char*)sseiPtr; */
/* while(*bytePtr){ */
/* if(*bytePtr == chara) { */
/* int i=1; */
/* while((pattern[i] )&&(bytePtr[i] == pattern[i])) i++; */
/* if(pattern[i] == 0) */
/* REPORT(bytePtr); */
/* if(bytePtr[i] == 0) */
/* return NULL; */
/* } */
/* bytePtr++; */
/* } */
/* } */
/* } */
/* return NULL; */
/* } */
#ifndef MAIN_C
#define MAIN_C
#include <stdio.h>
#include <stdlib.h>
#include "rdtsc.h"
size_t strlen_d(const char *str) ;
size_t strlen_l(const char *str);
size_t rb_strlen(const char *str);
char *strstrBerg (const char* phaystack, const char* pneedle);
char *strstrToy (const char* phaystack, const char* pneedle);
char *lstrstr (const char* , const char* );
char *lstrstrsse (const char* , const char* );
char *lstrstr5 (const char* , const char* );
char* strstra(const char *str,char c);
void printstr(char* s)
{
int i =0;
printf(":");
for(i=0;i<10;i++){
if(s[i] ==0)
goto ret;
printf("%c",s[i]);
}
ret:
printf("\n");
}
#define LOOPS 1
void test1(int argc,char** argv)
{
FILE* fp;
char* text;
char* textm;
int len = 1024*1024;
char pattern[64];
int testlen[20];
int i;
int textlen;
int patlen;
double t3;
char* findp;
textm = (char*) malloc(len+ 64);
text = (char*)(((unsigned long long) textm ) & ~63) +2;
fp = fopen(argv[1],"r");
if(fp ==NULL)
exit(0);
textlen= fread(text,1,1024*1024,fp);
text[textlen] = 0;
fclose(fp);
for(i=0;i<20;i++)
testlen[i] =i;
srand(clock());
for(patlen = 1;patlen < 20; patlen++){
int randloops = 0;
int k;
printf("*************************************\n");
printf("%the pattern len is %d \n",patlen);
randloops = rand() % 5 + 1;
for(k =0;k < randloops;k++){
int tmpstart = rand()% textlen;
while((tmpstart < textlen )&&(text[tmpstart] != ' ') )
tmpstart ++;
tmpstart ++;
if(tmpstart >= textlen)
continue;
for(i=0; i< patlen; i++)
pattern[i] = text[tmpstart + i];
pattern[i] =0;
printf("the pattern is :%s\n",pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = lstrstrsse(text,pattern);
t3= mdtime(1);
printf("lstrsse time:%15f :%d", t3,findp - text);
printstr(findp);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstr(text,pattern);
t3= mdtime(1);
printf("strstr time:%15f :%d", t3,findp - text);
printstr(findp);
printf("\n");
}
}
}
#include "defaultText.h"
int test2( int argc, char** argv)
{
char text0[] = TEXT;
char* patterns[] = {"vulture","emente", "MArs","dog","Z","ABG","do","AGB","animals are haunters of the battle field"};
char* pattern=patterns[0];
char text1[] = TEXT1;
char* patterns1[] = {"vulture","emente", "MArs","dog","Z","ABG","do","AGB","aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"};
char* pattern1=patterns1[0];
//char* pattern="dog";
//char* pattern="Z";
//char* pattern = "emente";
//char* pattern = "MArs";
char* findp;
char* textm;
char* text;
double t3;
int i,iter;
int len = 1024*1024;//strlen(text0);
//int len = strlen(text0);
textm = (char*) malloc(len+ 64);
text = (char*)(((unsigned long long) textm ) & ~63) ;
int n= strlen(text),m=strlen(pattern);
strcpy(text,text1);
for (iter=0;iter<9;iter++){
pattern1 = patterns1[iter];
n= strlen(text),m=strlen(pattern1);
printf ("===============sdfasd==================[%s]\n",pattern1);
printf("\n");
findp = Sbm2(text,pattern1, n, m);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = Sbm2(text,pattern1, n, m);
t3= mdtime(1);
printf("Sbm2 time:%15f :%d, [%s]", t3,findp - text, pattern1);
printf("\n");
findp = Sbm(text,pattern1);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = Sbm(text,pattern1);
t3= mdtime(1);
printf("Sbm time:%15f :%d, [%s]", t3,findp - text, pattern1);
printf("\n");
findp = strstrsse(text,pattern1);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstrsse(text,pattern1);
t3= mdtime(1);
printf("strstrsse time:%15f :%d, [%s]", t3,findp - text, pattern1);
printf("\n");
findp = strstr(text,pattern1);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstr(text,pattern1);
t3= mdtime(1);
printf("strstr time:%15f :%d, [%s]", t3,findp - text,pattern1);
printf("\n");
}
/* for(i=0;i<34;i++) */
/* { */
/* int j=0; */
/* for(j=0;j<i;j++) */
/* text[i] = 'a'; */
/* strcpy(text+i,text0); */
/* mdtime(0); */
/* findp = lstrstrsse(text,pattern); */
/* t3= mdtime(1); */
/* printf("lstrsse time:%15f :%d, [%s]", t3,findp - text,pattern); */
/* printstr(findp); */
/* } */
strcpy(text,text0);
//text = text0 ;
//for(i=0;i<len;i++){text[i] ='a';}
//text[i] =0;
n= strlen(text),m=strlen(pattern);
printf ("======string:[%d] pattern:[%d]\n",n,m);
for (iter=0;iter<9;iter++){
pattern = patterns[iter];
printf ("=================================[%s]\n",pattern);
printf("\n");
findp = lstrstr(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = lstrstr(text,pattern);
t3= mdtime(1);
printf("lstrstr time:%15f :%d. [%s]", t3,findp - text,pattern);
printstr(findp);
findp = lstrstrsse(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = lstrstrsse(text,pattern);
t3= mdtime(1);
printf("lstrsse time:%15f :%d, [%s]", t3,findp - text,pattern);
printstr(findp);
findp = strstr(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstr(text,pattern);
t3= mdtime(1);
printf("strstr time:%15f :%d, [%s]", t3,findp - text,pattern);
printstr(findp);
findp = strstr_fxxx(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstr_fxxx(text,pattern);
t3= mdtime(1);
printf("xxxxstrstr time:%15f :%d, [%s]", t3,findp - text,pattern);
printf("\n");
findp = (char *)MYSQLstrstr(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = MYSQLstrstr(text,pattern);
t3= mdtime(1);
printf("MYSQLstrstr time:%15f :%d, [%s]", t3,findp - text,pattern);
printf("\n");
findp = strstrBerg(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstrBerg(text,pattern);
t3= mdtime(1);
printf("strstrBerg time:%15f :%d, [%s]", t3,findp - text, pattern);
printstr(findp);
findp = strstrToy(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstrToy(text,pattern);
t3= mdtime(1);
printf("strstrToy time:%15f :%d, [%s]", t3,findp - text, pattern);
printstr(findp);
findp = Sbm2(text,pattern, n, m);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = Sbm2(text,pattern, n, m);
t3= mdtime(1);
printf("Sbm2 time:%15f :%d, [%s]", t3,findp - text, pattern);
printf("\n");
findp = Sbm(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = Sbm(text,pattern);
t3= mdtime(1);
printf("Sbm time:%15f :%d, [%s]", t3,findp - text, pattern);
printf("\n");
findp = strstrsse(text,pattern);
mdtime(0);
for(i=0;i<LOOPS;i++)
findp = strstrsse(text,pattern);
t3= mdtime(1);
printf("strstrsse time:%15f :%d, [%s]", t3,findp - text, pattern);
printf("\n");
}
/*result */
/* lstrstr time: 55682.000000 :4612. [vulture]:vulture do */
/* lstrsse time: 33407.000000 :4612, [vulture]:vulture do */
/* strstr time: 23771.000000 :4612, [vulture]:vulture do */
/* Bstrstr time: 82423.000000 :4612, [vulture]:vulture do */
/* strstrToy time: 80641.000000 :4612, [vulture]:vulture do */
/* mdtime(0); */
/* for(i=0;i<LOOPS;i++) */
/* len = strlen_d(text); */
/* t3= mdtime(1); */
/* printf("strlen_d time:%f :%d, [%s]\n", t3,len, pattern); */
/* mdtime(0); */
/* for(i=0;i<LOOPS;i++) */
/* len = strlen(text); */
/* t3= mdtime(1); */
/* printf("strlen time:%f :%d, [%s]\n", t3,len, pattern); */
/* mdtime(0); */
/* for(i=0;i<LOOPS;i++) */
/* len = strlen_l(text); */
/* t3= mdtime(1); */
/* printf("strlen_l time:%f :%d, [%s]\n", t3,len,pattern); */
/* mdtime(0); */
/* for(i=0;i<LOOPS;i++) */
/* len = rb_strlen(text); */
/* t3= mdtime(1); */
/* printf("rb_strlen time:%f :%d, [%s]\n", t3,len,pattern); */
/* mdtime(0); */
/* for(i=0;i<LOOPS;i++) */
/* len = rb_strlenSSE(text); */
/* t3= mdtime(1); */
/* printf("rb_strlenSSE time:%f :%d\n", t3,len); */
/* strlen_d time:16929.000000 :4624, [vulture] */
/* strlen time:34144.000000 :4624, [vulture] */
/* strlen_l time:9559.000000 :4624, [vulture] */
/* rb_strlen time:9284.000000 :4624, [vulture] */
}
int main( int argc, char** argv)
{
test2(argc,argv);
/* test1(argc,argv); */
Like("asdf",'q');
return 1;
}
#endif