e576bb2002-10-11Martin Nilsson /* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
134f292008-06-23Martin Stjernholm || $Id: pike_search_engine2.c,v 1.10 2008/06/23 19:30:42 mast Exp $
e576bb2002-10-11Martin Nilsson */
9b1f032000-10-09Fredrik Hübinette (Hubbe) /* * NCHAR = Needle character * HCHAR = Haystack character */ static INLINE HCHAR *NameNH(MEMCHR)(HCHAR *p, NCHAR c, ptrdiff_t e) { #if NSHIFT > HSHIFT if(c > (1<<(8*HSHIFT))) return 0; #endif return NameH(MEMCHR)(p,c,e); } static INLINE int NameNH(MEMCMP)(NCHAR *a, HCHAR *b, ptrdiff_t e) { #if NSHIFT == HSHIFT return MEMCMP(a, b, sizeof(HCHAR)*e); #else for(;e;e--,b++,a++) { if(*b!=*a) { if(*b<*a) return -1; if(*b>*a) return 1; } } return 0; #endif } INLINE HCHAR *NameNH(memchr_search)(void *data, HCHAR *haystack, ptrdiff_t haystacklen) {
0442612003-01-09Henrik Grubbström (Grubba)  return NameNH(MEMCHR)(haystack,
d2361e2003-06-30Martin Stjernholm  DO_NOT_WARN((NCHAR)(ptrdiff_t) PTR_TO_INT(data)),
0442612003-01-09Henrik Grubbström (Grubba)  haystacklen);
9b1f032000-10-09Fredrik Hübinette (Hubbe) } INLINE HCHAR *NameNH(memchr_memcmp)(NCHAR *needle, ptrdiff_t needlelen, HCHAR *haystack, ptrdiff_t haystacklen) { NCHAR c; HCHAR *end; if(needlelen > haystacklen) return 0; end=haystack + haystacklen - needlelen+1; c=needle[0]; needle++; needlelen--; while((haystack=NameNH(MEMCHR)(haystack,c,end-haystack))) if(!NameNH(MEMCMP)(needle,++haystack,needlelen)) return haystack-1; return 0; } #define make_memchr_memcmpX(X) \ HCHAR *PxC4(memchr_memcmp,X,NSHIFT,HSHIFT)(void *n, \ HCHAR *haystack, \ ptrdiff_t haystacklen) \ { \ return NameNH(memchr_memcmp)((NCHAR *)n, \ X, \ haystack, \ haystacklen); \ } make_memchr_memcmpX(2) make_memchr_memcmpX(3) make_memchr_memcmpX(4) make_memchr_memcmpX(5) make_memchr_memcmpX(6)
e3b79d2001-01-19Henrik Grubbström (Grubba) #undef make_memchr_memcmpX
9b1f032000-10-09Fredrik Hübinette (Hubbe)  HCHAR *NameNH(boyer_moore_hubbe)(struct boyer_moore_hubbe_searcher *s, HCHAR *haystack, ptrdiff_t haystacklen) {
134f292008-06-23Martin Stjernholm  NCHAR *needle = NEEDLE; ptrdiff_t nlen = NEEDLELEN; ptrdiff_t plen = s->plen; ptrdiff_t i=plen-1;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  ptrdiff_t hlen=haystacklen;
134f292008-06-23Martin Stjernholm  if(nlen > plen) hlen -= nlen-plen;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  restart: while(i<hlen) { ptrdiff_t k,j; if((k=s->d1[ NameNH(BMHASH)( haystack[i] ) ])) i+=k; else { #if NSHIFT == 0
134f292008-06-23Martin Stjernholm  j=plen-1;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  #ifdef PIKE_DEBUG
134f292008-06-23Martin Stjernholm  if(needle[j] != haystack[i])
5aad932002-08-15Marcus Comstedt  Pike_fatal("T2BM failed!\n");
9b1f032000-10-09Fredrik Hübinette (Hubbe) #endif #else i++;
134f292008-06-23Martin Stjernholm  j=plen;
9b1f032000-10-09Fredrik Hübinette (Hubbe) #endif
134f292008-06-23Martin Stjernholm  while(needle[--j] == haystack[--i])
9b1f032000-10-09Fredrik Hübinette (Hubbe)  { if(!j) {
134f292008-06-23Martin Stjernholm  if(nlen > plen)
9b1f032000-10-09Fredrik Hübinette (Hubbe)  {
134f292008-06-23Martin Stjernholm  if(!NameNH(MEMCMP)(needle+plen, haystack+i+plen, nlen-plen))
9b1f032000-10-09Fredrik Hübinette (Hubbe)  { return haystack+i; }else{ /* this can be optimized... */
134f292008-06-23Martin Stjernholm  i+=plen;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  goto restart; } }else{ return haystack+i; } } } i+= (s->d1[ NameNH(BMHASH)(haystack[i]) ] >= s->d2[j]) ? (s->d1[ NameNH(BMHASH)(haystack[i]) ]): (s->d2[j]); } } return 0; } HCHAR *NameNH(hubbe_search)(struct hubbe_searcher *s, HCHAR *haystack, ptrdiff_t haystacklen) {
134f292008-06-23Martin Stjernholm  NCHAR *needle = NEEDLE; ptrdiff_t nlen = NEEDLELEN; size_t hsize = s->hsize; size_t max = s->max;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  INT32 tmp, h; HCHAR *q, *end; register struct hubbe_search_link *ptr; end=haystack+haystacklen;
134f292008-06-23Martin Stjernholm  q=haystack + max - 4;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  NameH(HUBBE_ALIGN)(q);
134f292008-06-23Martin Stjernholm  for(;q<=end-sizeof(INT32);q+=max)
9b1f032000-10-09Fredrik Hübinette (Hubbe)  { h=tmp=NameH(GET_4_ALIGNED_CHARS)(q); h+=h>>7; h+=h>>17;
134f292008-06-23Martin Stjernholm  h&=hsize;
9b1f032000-10-09Fredrik Hübinette (Hubbe)  for(ptr=s->set[h];ptr;ptr=ptr->next) { HCHAR *where; if(ptr->key != tmp) continue; where=q-ptr->offset; /* FIXME: This if statement is not required * HUBBE_ALIGN is a noop */ if(where<haystack) continue;
134f292008-06-23Martin Stjernholm  if(where+nlen>end) return 0;
9b1f032000-10-09Fredrik Hübinette (Hubbe) 
134f292008-06-23Martin Stjernholm  if(!NameNH(MEMCMP)(needle,where,nlen))
9b1f032000-10-09Fredrik Hübinette (Hubbe)  return where; } } return 0; }