On Thu, Apr 16, 2009 at 09:09:44PM +0200, Ondrej Bilka wrote:
> Hello. I am writing partial fnmatch to speed up locate et al. 
> Idea is save state state to match common prefix only once.
Forgot attach code.


-- 

Browser's cookie is corrupted -- someone's been nibbling on it.
#include <stdint.h>
#include <fnmatch.h>
#include <stdio.h>
#include <string.h>
#define UINT uint32_t
#define UINTSIZE 4
typedef struct {	char tp;
} pattern;
typedef struct {	char tp;
	char chr;
} char_pattern;
typedef struct {	char tp;
	UINT chars;
} chars_pattern;
typedef struct {	char tp;
} qst_pattern;
typedef struct {	char tp;
	char chr;
	short sizerest;
} star_pattern;
typedef struct {	char tp;
} end_pattern;
typedef struct {	char tp;
} endstar_pattern;

enum PATTERNS {PATTERN_char,PATTERN_qst,PATTERN_star,PATTERN_chars,PATTERN_end,PATTERN_endstar};


#define NEXTPATTERN(type) pat->tp=PATTERN_##type;pat+=sizeof(type##_pattern);
pattern *makepattern(char *str){
  unsigned	char *s;
	pattern *pat,*ret;
	int canpack;int i,m;
	ret=pat=(pattern *) malloc(200);
	int rest=0;
	for (s=(unsigned char *)str;*s;s++) {
		if (*s!='*') rest++;
	}
	for (s=(unsigned char *)str;*s;s++) {
		switch(*s){
			case '*':
				while (*(s+1)=='?') {/* *?=?*  */
					NEXTPATTERN(qst)
					rest--;
					s++;
				}
				if (*(s+1)){
					((star_pattern*) pat)->sizerest=rest;
					((star_pattern*) pat)->chr=*(s+1);
					s++;
					NEXTPATTERN(star)
				}else{
					NEXTPATTERN(endstar)
				}
				break;
			case '?':
				NEXTPATTERN(qst)
				rest--;
				break;
			default:
				canpack=1;
				for (i=0;i<4;i++)
					if (*(s+i)=='*'||*(s+i)=='?') canpack=0;
				if (canpack){
					((chars_pattern*) pat)->chars=*((UINT*) s);
					rest-=UINTSIZE;
					s+=UINTSIZE-1;
					NEXTPATTERN(chars)
				}else{
				((char_pattern*) pat)->chr=*s;
				rest--;
				NEXTPATTERN(char)
				}
				break;
		}
			
	}
	NEXTPATTERN(end)
	return ret; 
}
#undef NEXTPATTERN
#define NEXTPATTERN(type) p+=sizeof(type##_pattern);
int fnmatch3(pattern *p,char *str,int len){
	char *s=str; int i,j; int sizerest,chars,chr;
	while (1){
		switch (p->tp){
			case PATTERN_char:
				if (*s != ((char_pattern*) p )->chr) return 1;
				NEXTPATTERN(char);
				s++;
			break;
			case PATTERN_chars:
				if ((* (UINT *)s)!=((chars_pattern*) p )->chars) return 1;
				s+=UINTSIZE;
				NEXTPATTERN(chars);
			break;
			case PATTERN_qst:
				s+=1;
				NEXTPATTERN(qst);
			break;
			case PATTERN_star:
				sizerest=((star_pattern*) p)->sizerest;
				chr=((star_pattern*) p)->chr;
				NEXTPATTERN(star);
				for (i=s-str;i<=len-sizerest ; i++ )
				{
					if (( *(str+i) == chr)
					 && !fnmatch3(p,str+i+1,len-i-1)) return 0;
				}
				return 1;
			break;
			case PATTERN_end:
				return *s;
			break;
			case PATTERN_endstar:
				return 0;
			break;
		}
	}
}
char buf[1000];
int fnmatch2(pattern *p, char *str,int flags){
	char *bu=buf;
	if (flags){
		while (*str) *bu++=tolower(*str++);
		str=buf;
	}
	return fnmatch3(p,str,strlen(str));
}
int main(){int i;
	char ptr[]="*abc*";
	pattern *p=makepattern(ptr);
	int cnt=0;
	char s1[]="abcda", s2[]="bbida",s3[]="nabcx";
	for (i=0;i<1000000;i++) {
		s1[1]++;s2[1]++;s3[1]++;
	int flags=1<<4;
#ifdef COMPARE
		cnt+=fnmatch(ptr,s1,flags)+fnmatch(ptr,s2,flags)+fnmatch(ptr,s3,flags);
#else
		cnt+=fnmatch2(p,s1,flags)+fnmatch2(p,s2,flags)+fnmatch2(p,s3,flags);
#endif
	}
	printf("%i",cnt);
}
_______________________________________________
Bug-coreutils mailing list
[email protected]
http://lists.gnu.org/mailman/listinfo/bug-coreutils

Reply via email to