示例#1
0
/* Compute one operation and store result */
static int
perform(UDM_BOOLSTACK *s, int com)
{
  unsigned long res,x1,x2;
  switch(com)
  {
    case UDM_STACK_OR:
      /* This is to avoid compiler      */
      /* optimization in || calculation */
      x1=POPARG(s);
      x2=POPARG(s);
      res=(x1||x2);
#ifdef DEBUG_BOOL
      fprintf(stderr,"Perform %lu | %lu\n",x1,x2);
#endif
      PUSHARG(s,res);
      break;
    case UDM_STACK_AND:
      x1=POPARG(s);
      x2=POPARG(s);
      res=(x1&&x2);
#ifdef DEBUG_BOOL
      fprintf(stderr,"Perform %lu & %lu\n",x1,x2);
#endif
      PUSHARG(s,res);
      break;
    case UDM_STACK_NOT:
      x1=POPARG(s);
      res=x1?0:1;
#ifdef DEBUG_BOOL
      fprintf(stderr,"Perform ~%lu\n",x1);
#endif
      PUSHARG(s,res);
      break;
  }
  return(0);
}
示例#2
0
/* Main function to calculate items sequence */
int DpsCalcBoolItems(DPS_AGENT *query, DPS_RESULT *Res) {
  DPS_BOOLSTACK *s = DpsBoolStackInit(NULL);
  DPS_STACK_ITEM *items = Res->items, *res;
  DPS_WIDEWORD Word;
  size_t nitems = Res->nitems;
  size_t i, j;
  int first_time = (Res->WWList.nwords == 0);

  if (s == NULL) return DPS_STACK_ERR;
  if (nitems == 0) {
    Res->CoordList.Coords = Res->items[0].pbegin;
    Res->items[0].pbegin = NULL;
    Res->items[0].count = 0;
/*    Res->CoordList.ncoords = Res->items[0]->count;*/
    DpsBoolStackFree(s);
    return DPS_OK;
  }

  for (i = 0; i < nitems; i++) {
    if (items[i].cmd != DPS_STACK_WORD) continue;
    if ((items[i].pbegin == NULL) && ((items[i].origin & DPS_WORD_ORIGIN_STOP) == 0)) {
      for(j = 0; j < i; j++) 
	if (items[j].crcword == items[i].crcword) break;
      if (j < i) {
	items[i].count = items[j].count;
	items[i].pbegin = (DPS_URL_CRD_DB*)DpsMalloc((items[j].count + 1) * sizeof(DPS_URL_CRD_DB));
	if (items[i].pbegin == NULL) {
	  DpsLog(query, DPS_LOG_ERROR, "Can't alloc %d bytes %s:%d", (items[j].count + 1) * sizeof(DPS_URL_CRD_DB), __FILE__, __LINE__);
	  DpsBoolStackFree(s);
	  return DPS_STACK_ERR;
	}
	{
	  register size_t z;
	  for (z = 0; z < items[i].count; z++) {
	    items[i].pbegin[z] = items[j].pbegin[z];
	    items[i].pbegin[z].coord &= 0xFFFFFF00;
	    items[i].pbegin[z].coord += (items[i].wordnum & 0xFF);
	  }
	}
      }
    }
    if (first_time) {
      Word.order = items[i].order;
      Word.count = items[i].count;
      Word.crcword = items[i].crcword;
      Word.word = items[i].word;
      Word.uword = items[i].uword;
      Word.origin = items[i].origin;
      DpsWideWordListAdd(&Res->WWList, &Word, DPS_WWL_LOOSE);
    }
  }

#ifdef DEBUG_BOOL
  DpsLog(query, DPS_LOG_EXTRA, "--------");
  for(i=0;i<nitems;i++){
    DpsLog(query, DPS_LOG_EXTRA, "[%d].%d %c : %d -- %s", 
	   i, items[i].wordnum, item_type(items[i].cmd), items[i].count, (items[i].word == NULL) ? "<NULL>" : items[i].word);
  }
  DpsLog(query, DPS_LOG_EXTRA, "--------");
#endif
  for(i=0;i<nitems;i++){
    int c;
#ifdef DEBUG_BOOL
    DpsLog(query, DPS_LOG_EXTRA,
	   ".[%d].%d %c : %d -- %s, (order_origin:%d)", i, items[i].wordnum, item_type(items[i].cmd), items[i].count, (items[i].word == NULL) ? "<NULL>" : items[i].word, items[i].order_origin);
#endif
    switch(c=items[i].cmd){
    case DPS_STACK_RIGHT:
      /* Perform till LEFT bracket */
      while((TOPCMD(s) != DPS_STACK_LEFT) && (TOPCMD(s) != DPS_STACK_BOT))
	if (DPS_OK != perform(query, Res, s, POPCMD(s))) {
	  DpsBoolStackFree(s);
	  return DPS_STACK_ERR;
	}
      /* Pop LEFT bracket itself */
      if(TOPCMD(s) == DPS_STACK_LEFT)
	POPCMD(s);
      break;
    case DPS_STACK_OR:
    case DPS_STACK_AND:
    case DPS_STACK_NEAR:
    case DPS_STACK_ANYWORD:
      if (s->nastack > 1)
	while(c <= TOPCMD(s)) {
	  if (DPS_OK != perform(query, Res, s, POPCMD(s))) {
	    DpsBoolStackFree(s);
	    return DPS_STACK_ERR;
	  }
	}
      /* IMPORTANT! No break here! That's OK*/
      /* Так надо ! */
    case DPS_STACK_LEFT:
    case DPS_STACK_PHRASE_LEFT:
    case DPS_STACK_NOT:
      if (PUSHCMD(s,c) != DPS_OK) {
	DpsBoolStackFree(s);
	return DPS_STACK_ERR;
      }
      break;
    case DPS_STACK_PHRASE_RIGHT:
      /* perform till RIGHT phrase quote */
      while((TOPCMD(s) != DPS_STACK_PHRASE_LEFT) && (TOPCMD(s) != DPS_STACK_BOT))
	if (DPS_OK != perform(query, Res, s, POPCMD(s))) {
	  DpsBoolStackFree(s);
	  return DPS_STACK_ERR;
	}
      if (TOPCMD(s) == DPS_STACK_PHRASE_LEFT) perform(query, Res, s, POPCMD(s));
#ifdef DEBUG_BOOL
      DpsLog(query, DPS_LOG_EXTRA, "[%d] %c", i, item_type(items[i].cmd));
#endif
      break;
    case DPS_STACK_WORD:
      items[i].order_from = items[i].order_to = items[i].order;
    default:
      if (DPS_OK != PUSHARG(s, &items[i])) {
	DpsBoolStackFree(s);
	return DPS_STACK_ERR;
      }
      items[i].pbegin = items[i].plast = NULL; /*items[i].word = NULL; items[i].uword = NULL;*/
/*      items[i].count = 0;*/

/*				DpsStackItemFree(&items[i]);*/
/*			        if (DPS_OK != PUSHARG(s, (count[items[i].order]) ? 1UL : 0UL)) {
				  DpsBoolStackFree(s);
				  return DPS_STACK_ERR;
				}*/
      break;
    }
  }
  while(TOPCMD(s) != DPS_STACK_BOT) {
    if (DPS_OK != perform(query, Res, s, POPCMD(s))) {
      DpsBoolStackFree(s);
      return DPS_STACK_ERR;
    }
  }
  res = POPARG(s);
  if (res != NULL) {
    Res->CoordList.Coords = res->pbegin;
    Res->CoordList.ncoords = res->count;
    res->pbegin = res->plast = NULL;
/*    res->count = 0;*/
    DpsStackItemFree(res);
  }
#ifdef DEBUG_BOOL
  DpsLog(query, DPS_LOG_EXTRA, "result: %x", res);
#endif
  DpsBoolStackFree(s);
  return DPS_OK;
}
示例#3
0
/* Compute one operation and store result */
static int perform(DPS_AGENT *query, DPS_RESULT *Res, DPS_BOOLSTACK *s, int com) {
	DPS_STACK_ITEM res, *x1, *x2;
	int rc = DPS_OK, found, flag1;

	bzero(&res, sizeof(res));
	switch(com){
	        case DPS_STACK_PHRASE_LEFT:
		  x1 = POPARG(s);
		  if (x1 == NULL) {
		    bzero(&res, sizeof(res));
		    
		  } else {
		    res = *x1; /* FIXME: add checking ? */
		    if (res.order_from != res.order_to) {
		      DPS_URL_CRD_DB *w;
		      dps_uint4 *pos_real, *order_ideal, *order_real, *gap_ahead/*, *gap_back*/;
		      urlid_t curlid;
		      size_t nwords = res.order_to - res.order_from + 1, nonstop_words;
		      size_t p_cmp, p_ins;
		      res.plast = res.pbegin + res.count;
		      w = res.pcur = res.pchecked = res.pbegin;
		      if ((pos_real = (dps_uint4*)DpsMalloc(5 * nwords * sizeof(dps_uint4) + 1)) == NULL) {
			DpsLog(query, DPS_LOG_ERROR, "Can't alloc %d bytes %s:%d",(5 * nwords * sizeof(dps_uint4) + 1), __FILE__, __LINE__);
			return DPS_ERROR;
		      }
		      order_real = pos_real + nwords;
		      gap_ahead = order_real + nwords;
		      order_ideal = gap_ahead + nwords;
/*		    gap_back = order_ideal + nwords;*/
		      nonstop_words = 0;
		      { register size_t tt;
			for (tt = res.order_from; tt <= res.order_to; tt++) {
#ifdef DEBUG_BOOL
			  
#endif
			  if ((Res->items[tt].order_origin & DPS_WORD_ORIGIN_STOP) == 0) {
			    order_ideal[nonstop_words] = tt;
			    gap_ahead[nonstop_words] = (tt == res.order_to) ? 0 : 1;
			    { register size_t zz;
			      for (zz = tt + 1; zz <= res.order_to; zz++) {
				if (Res->items[zz].order_origin & DPS_WORD_ORIGIN_STOP) gap_ahead[nonstop_words]++;
				else break;
			      }
			    }
			    nonstop_words++;
			  }
			}
		      }

#ifdef DEBUG_BOOL
		      DpsLog(query, DPS_LOG_EXTRA, "nonstopwords: %d  nwords:%d", nonstop_words, nwords);
		      { register size_t tt;
			for (tt = 0; tt < nonstop_words; tt++) {
			  DpsLog(query, DPS_LOG_EXTRA, "%d:order_ideal:%d  gap_ahead:%d", tt, order_ideal[tt], gap_ahead[tt]);
			}
		      }
#endif
		      if (nonstop_words != 0) {
			while (res.pcur < res.plast) {
			  register size_t tt;
			  curlid = res.pcur->url_id;
			  found = 0;
			  p_ins = 0;
			  p_cmp = nwords - nonstop_words;
			  res.pchecked = res.pcur; /******* ? *****/
			  for (tt = 0; tt < nwords - nonstop_words; tt++) pos_real[tt] = 0;
			  for (tt = 0; (tt < nonstop_words) && (res.pcur < res.plast) && (res.pcur->url_id == curlid) ; tt++) {
			    order_real[p_ins] = Res->WWList.Word[DPS_WRDNUM(res.pcur->coord)].order;
			    pos_real[p_ins] = DPS_WRDPOS(res.pcur->coord);
			    while((res.pcur < res.plast) && (pos_real[p_ins] == DPS_WRDPOS(res.pcur->coord))) res.pcur++;
			    p_ins++; p_cmp++;
			    p_ins %= nwords;
			    p_cmp %= nwords;
			  }
			  if (tt == nonstop_words) {
/* [[[[[[ */
			    found = 1;
			    for (tt = 0; tt < nonstop_words; tt++) {
			      if (order_real[(p_cmp + tt) % nwords] != order_ideal[tt]) {
				found = 0; break;
			      }
			      if (gap_ahead[tt] && (tt + gap_ahead[tt] < nwords) && 
				  (pos_real[(p_cmp + tt) % nwords] + gap_ahead[tt] != pos_real[(p_cmp + tt + 1) % nwords])) {
				found = 0; break;
			      }
			    }
			    if (found) {
			      while((res.pchecked < res.pcur) /*&& (res.pchecked->url_id == curlid)*/) {
				*w = *res.pchecked;
				w++; res.pchecked++;
			      }
			      res.pcur = res.pchecked;
			    } else {
			      res.pchecked = res.pcur;
			    }
/* ]]]]]] */			    
			  }
			  while (/*(found == 0) &&*/ (res.pcur < res.plast) && (res.pcur->url_id == curlid)) {
			    order_real[p_ins] = Res->WWList.Word[DPS_WRDNUM(res.pcur->coord)].order;
			    pos_real[p_ins] = DPS_WRDPOS(res.pcur->coord);
			    while((res.pcur < res.plast) && (pos_real[p_ins] == DPS_WRDPOS(res.pcur->coord))) res.pcur++;
			    p_ins++; p_cmp++;
			    p_ins %= nwords;
			    p_cmp %= nwords;
/* [[[[[[ */
			    found = 1;
			    for (tt = 0; tt < nonstop_words; tt++) {
			      if (order_real[(p_cmp + tt) % nwords] != order_ideal[tt]) {
				found = 0; break;
			      }
			      if (gap_ahead[tt] && (tt + gap_ahead[tt] < nwords) && 
				  (pos_real[(p_cmp + tt) % nwords] + gap_ahead[tt] != pos_real[(p_cmp + tt + 1) % nwords])) {
				found = 0; break;
			      }
			    }
			    if (found) {
			      while((res.pchecked < res.pcur) /*&& (res.pchecked->url_id == curlid)*/) {
				*w = *res.pchecked;
				w++; res.pchecked++;
			      }
			      res.pcur = res.pchecked;
			    } else {
			      res.pchecked = res.pcur;
			    }
/* ]]]]]] */
			  }
			
			}
		      }
		      res.count = w - res.pbegin;
		      DPS_FREE(pos_real);
		    }
		  }
#ifdef DEBUG_BOOL
		  DpsLog(query, DPS_LOG_EXTRA,
			 "Perform <{%d}:%d:%d> ->{%d}", x1 ? x1->count : 0, x1 ? x1->order_from : 0, x1 ? x1->order_to : 0, res.count);
#endif
		  rc = PUSHARG(s, &res);
		  break;
		case DPS_STACK_OR:
			x1 = POPARG(s);
			x2 = POPARG(s);
			if (x2 == NULL || x1 == NULL) {
			  if (x1 != NULL) { res = *x1; x1 = NULL; }
			  if (x2 != NULL) { res = *x2; x2 = NULL; }
			} else {
#ifdef DEBUG_BOOL
/*			  printBoolRes(query, x1);*/
			  DpsLog(query, DPS_LOG_EXTRA, "^^^");
/*			  printBoolRes(query, x2);*/
#endif
			res.order_from = (x1->order_from <= x2->order_from) ? x1->order_from : x2->order_from;
			res.order_to = (x1->order_to >= x2->order_to) ? x1->order_to : x2->order_to;
			
			if (DPS_OK != proceedOR(query, &res, x1, x2)) return DPS_ERROR;
			DpsStackItemFree(x1); DpsStackItemFree(x2);
			res.count = res.pcur - res.pbegin;
			{ register size_t tt; int x1origin=0, x2origin=0;
			  for (tt = x1->order_from; tt <= x1->order_to; tt++) {
#ifdef DEBUG_BOOL
			    DpsLog(query, DPS_LOG_EXTRA, "\t\t\t\tx1order_origin[%d].%x ", tt, Res->items[tt].origin /*order_origin*/);
#endif
			    if (Res->items[tt].origin /*order_origin*/ & DPS_WORD_ORIGIN_STOP) {
			      x1origin = Res->items[tt].origin /*order_origin*/;
			      break;
			    }
			  }
			  for (tt = x2->order_from; tt <= x2->order_to; tt++) {
#ifdef DEBUG_BOOL
			    DpsLog(query, DPS_LOG_EXTRA, "\t\t\t\tx2order_origin[%d].%x ", tt, Res->items[tt].origin /*order_origin*/);
#endif
			    if (Res->items[tt].origin /*order_origin*/ & DPS_WORD_ORIGIN_STOP) {
			      x2origin = Res->items[tt].origin /*order_origin*/;
			      break;
			    }
			  }
			  
			  x1origin = x1->origin; x2origin = x2->origin;
#ifdef DEBUG_BOOL
			  DpsLog(query, DPS_LOG_EXTRA, "\t\t\t\tx1origin.%x x2origin.%x", x1origin, x2origin);
#endif


			  if ((x1origin & (DPS_WORD_ORIGIN_STOP | DPS_WORD_ORIGIN_QUERY)) == (DPS_WORD_ORIGIN_STOP|DPS_WORD_ORIGIN_QUERY)) {
			    res.origin = x1origin;
			  } else
			  if ((x2origin & (DPS_WORD_ORIGIN_STOP | DPS_WORD_ORIGIN_QUERY)) == (DPS_WORD_ORIGIN_STOP|DPS_WORD_ORIGIN_QUERY)) {
			    res.origin = x2origin;
			  } else
			  if (((x1origin & DPS_WORD_ORIGIN_STOP) && (x2origin & DPS_WORD_ORIGIN_STOP)) ||
			      ( (res.count == 0) && 
				((x1origin & DPS_WORD_ORIGIN_STOP) || (x2origin & DPS_WORD_ORIGIN_STOP))))
			    res.origin = DPS_WORD_ORIGIN_STOP;
			  if ((x1origin & DPS_WORD_ORIGIN_ACRONYM) && (x1origin & DPS_WORD_ORIGIN_ACRONYM)) 
			    res.origin |= DPS_WORD_ORIGIN_ACRONYM;
			}
			}
#ifdef DEBUG_BOOL
			DpsLog(query, DPS_LOG_EXTRA, "Perform {%d}.%x | {%d}.%x -> {%d}.%x",
			       (x1) ? x1->count:-1, (x1)?x1->origin:-1, (x2)?x2->count : -1, (x2) ? x2->origin : -1, res.count, res.origin);
/*			printBoolRes(query, &res);*/
			DpsLog(query, DPS_LOG_EXTRA, "===");
#endif
			rc = PUSHARG(s, &res);
			break;
	        case DPS_STACK_NEAR:
			x1 = POPARG(s);
			x2 = POPARG(s);
			if (x2 == NULL || x1 == NULL) {
			  if (x1 != NULL) { res = *x1; x1 = NULL; }
			  if (x2 != NULL) { res = *x2; x2 = NULL; }
			} else {
			  res.order_from = (x1->order_from <= x2->order_from) ? x1->order_from : x2->order_from;
			  res.order_to = (x1->order_to >= x2->order_to) ? x1->order_to : x2->order_to;
			  if ((x1->origin & DPS_WORD_ORIGIN_STOP) && (x2->origin & DPS_WORD_ORIGIN_STOP) ) {
			    if (DPS_OK != proceedOR(query, &res, x1, x2)) return DPS_ERROR;
			    res.origin = DPS_WORD_ORIGIN_STOP;
			  } else if (x2->origin & DPS_WORD_ORIGIN_STOP) {
			    if (DPS_OK != proceedSTOP(query, &res, x1, x2)) return DPS_ERROR;
			  } else if (x1->origin & DPS_WORD_ORIGIN_STOP ) {
			    if (DPS_OK != proceedSTOP(query, &res, x2, x1)) return DPS_ERROR;
			  } else if (!((x1->cmd & DPS_STACK_WORD_NOT) && (x2->cmd & DPS_STACK_WORD_NOT))) {
#ifdef DEBUG_BOOL
/*			    printBoolRes(query, x1);*/
			    DpsLog(query, DPS_LOG_EXTRA, "^^^");
			    DpsLog(query, DPS_LOG_DEBUG, "x1.NOT: %d  x2.NOT: %d", x1->cmd & DPS_STACK_WORD_NOT, x2->cmd & DPS_STACK_WORD_NOT);
/*			    printBoolRes(query, x2);*/
#endif
			    res.pbegin = res.pcur = (DPS_URL_CRD_DB*)DpsMalloc((x1->count + x2->count + 1) * sizeof(DPS_URL_CRD_DB));
			    if (res.pbegin == NULL) return DPS_ERROR;
			    x1->pcur = x1->pbegin; x1->plast = x1->pbegin + x1->count;
			    x2->pcur = x2->pbegin; x2->plast = x2->pbegin + x2->count;
			    if (x1->cmd & DPS_STACK_WORD_NOT) {
			      register DPS_STACK_ITEM *t = x1;
			      x1 = x2; x2 = t;
			    }
			    while (x1->pcur < x1->plast && x2->pcur < x2->plast) {
			      while ((x2->pcur < x2->plast) && (x2->pcur->url_id < x1->pcur->url_id)) x2->pcur++;
			      if (x2->pcur >= x2->plast) break;
			      if (x2->pcur->url_id == x1->pcur->url_id) {
				dps_uint4 pos1 = DPS_WRDPOS(x1->pcur->coord);
				dps_uint4 pos2 = DPS_WRDPOS(x2->pcur->coord);
				register urlid_t curlid = x1->pcur->url_id;
				if (pos1 > pos2) { found = ((pos2 + 16) >= pos1);
				} else { found = ((pos1 + 16) >= pos2);
				}
				x1->pchecked = x1->pcur; x2->pchecked = x2->pcur;
				while ((!found) && (x1->pchecked < x1->plast) && (x2->pchecked < x2->plast) 
				       /*&& (x1->pchecked->url_id == x2->pchecked->url_id)*/ ) {
				  if (x1->pchecked->coord <= x2->pchecked->coord) {
				    x1->pchecked++;
				    pos1 = DPS_WRDPOS(x1->pchecked->coord);
				    if (x1->pchecked->url_id != curlid) break;
				  } else {
				    x2->pchecked++;
				    pos2 = DPS_WRDPOS(x2->pchecked->coord);
				    if (x2->pchecked->url_id != curlid) break;
				  }
				  if (pos1 > pos2) { found = ((pos2 + 16) >= pos1);
				  } else { found = ((pos1 + 16) >= pos2);
				  }
				}
				if (x2->cmd & DPS_STACK_WORD_NOT || x1->cmd & DPS_STACK_WORD_NOT) found = !found;
				if (found) {

				  while ((x1->pcur < x1->plast) && (x2->pcur < x2->plast) /*&& (x1->pcur->url_id == x2->pcur->url_id)*/) {
				    if (x1->pcur->coord <= x2->pcur->coord) {
				      *res.pcur = *x1->pcur;
				      res.pcur++; x1->pcur++; if (x1->pcur->url_id != curlid) break;
				    } else {
				      *res.pcur = *x2->pcur;
				      res.pcur++; x2->pcur++; if (x2->pcur->url_id != curlid) break;
				    }
				  }
				  while ((x1->pcur < x1->plast) && (x1->pcur->url_id == curlid)) {
				    *res.pcur = *x1->pcur;
				    res.pcur++; x1->pcur++;
				  }
				  while ((x2->pcur < x2->plast) && (x2->pcur->url_id == curlid)) {
				    *res.pcur = *x2->pcur;
				    res.pcur++; x2->pcur++;
				  }

				} else {
				  x1->pcur = x1->pchecked; x2->pcur = x2->pchecked;
				  while ((x1->pcur < x1->plast) && (x1->pcur->url_id == curlid)) x1->pcur++;
				  while ((x2->pcur < x2->plast) && (x2->pcur->url_id == curlid)) x2->pcur++;
				}
			      } else {
				register DPS_STACK_ITEM *t = x1;
				x1 = x2; x2 = t;
			      }
			    }
			  }
			}
			DpsStackItemFree(x1); DpsStackItemFree(x2);
			res.count = res.pcur - res.pbegin;
#ifdef DEBUG_BOOL
			DpsLog(query, DPS_LOG_EXTRA,"Perform {%d}.%x NEAR {%d}.%x - > %d.%d", 
			       (x1)?x1->count:-1, (x1)?x1->origin:-1, (x2) ? x2->count : -1, (x2) ? x2->origin: - 1, res.count, res.origin);
/*			printBoolRes(query, &res);*/
			DpsLog(query, DPS_LOG_EXTRA, "===");
#endif
			rc = PUSHARG(s, &res);
			break;
	        case DPS_STACK_ANYWORD:
			x1 = POPARG(s);
			x2 = POPARG(s); flag1 = 0;
			if (x2 == NULL || x1 == NULL) {
			  if (x1 != NULL) { res = *x1; x1 = NULL; }
			  if (x2 != NULL) { res = *x2; x2 = NULL; }
			} else {
			  res.order_from = (x1->order_from <= x2->order_from) ? x1->order_from : x2->order_from;
			  res.order_to = (x1->order_to >= x2->order_to) ? x1->order_to : x2->order_to;
			  if ((x1->origin & DPS_WORD_ORIGIN_STOP) && (x2->origin & DPS_WORD_ORIGIN_STOP) ) {
			    if (DPS_OK != proceedOR(query, &res, x1, x2)) return DPS_ERROR;
			    res.origin = DPS_WORD_ORIGIN_STOP;
			  } else if (x2->origin & DPS_WORD_ORIGIN_STOP) {
			    if (DPS_OK != proceedSTOP(query, &res, x1, x2)) return DPS_ERROR;
			  } else if (x1->origin & DPS_WORD_ORIGIN_STOP ) {
			    if (DPS_OK != proceedSTOP(query, &res, x2, x1)) return DPS_ERROR;
			  } else if (!((x1->cmd & DPS_STACK_WORD_NOT) && (x2->cmd & DPS_STACK_WORD_NOT))) {
			    res.pbegin = res.pcur = (DPS_URL_CRD_DB*)DpsMalloc((x1->count + x2->count + 1) * sizeof(DPS_URL_CRD_DB));
			    if (res.pbegin == NULL) return DPS_ERROR;
			    x1->pcur = x1->pbegin; x1->plast = x1->pbegin + x1->count;
			    x2->pcur = x2->pbegin; x2->plast = x2->pbegin + x2->count;
			    if (x1->cmd & DPS_STACK_WORD_NOT) {
			      register DPS_STACK_ITEM *t = x1;
			      x1 = x2; x2 = t; flag1 = !flag1;
			    }
			    while (x1->pcur < x1->plast && x2->pcur < x2->plast) {
			      while ((x2->pcur < x2->plast) && (x2->pcur->url_id < x1->pcur->url_id)) x2->pcur++;
			      if (x2->pcur >= x2->plast) break;
			      if (x2->pcur->url_id == x1->pcur->url_id) {
				dps_int4 pos1 = (dps_int4)DPS_WRDPOS(x1->pcur->coord);
				dps_int4 pos2 = (dps_int4)DPS_WRDPOS(x2->pcur->coord);
				register urlid_t curlid = x1->pcur->url_id;
				found = ((flag1) ? ((pos1 + 2) == pos2) : ((pos2 + 2) == pos1));
				x1->pchecked = x1->pcur; x2->pchecked = x2->pcur;
				while ((!found) && (x1->pchecked < x1->plast) && (x2->pchecked < x2->plast) 
				       && (x1->pchecked->url_id == x2->pchecked->url_id)) {
				  if (x1->pchecked->coord <= x2->pchecked->coord) {
				    x1->pchecked++;
				    pos1 = (dps_int4)DPS_WRDPOS(x1->pchecked->coord);
				  } else {
				    x2->pchecked++;
				    pos2 = (dps_int4)DPS_WRDPOS(x1->pchecked->coord);
				  }
				  found = ((flag1) ? ((pos1 + 2) == pos2) : ((pos2 + 2) == pos1));
				}
				if (x2->cmd & DPS_STACK_WORD_NOT || x1->cmd & DPS_STACK_WORD_NOT) found = !found;
				if (found) {
				  while ((x1->pcur < x1->plast) && (x2->pcur < x2->plast) && (x1->pcur->url_id == x2->pcur->url_id)) {
				    if (x1->pcur->coord <= x2->pcur->coord) {
				      *res.pcur = *x1->pcur;
				      res.pcur++; x1->pcur++;
				    } else {
				      *res.pcur = *x2->pcur;
				      res.pcur++; x2->pcur++;
				    }
				  }
				  while ((x1->pcur < x1->plast) && (x1->pcur->url_id == curlid)) {
				    *res.pcur = *x1->pcur;
				    res.pcur++; x1->pcur++;
				  }
				  while ((x2->pcur < x2->plast) && (x2->pcur->url_id == curlid)) {
				    *res.pcur = *x2->pcur;
				    res.pcur++; x2->pcur++;
				  }
				} else {
				  x1->pcur = x1->pchecked; x2->pcur = x2->pchecked;
				  while ((x1->pcur < x1->plast) && (x1->pcur->url_id == curlid)) x1->pcur++;
				  while ((x2->pcur < x2->plast) && (x2->pcur->url_id == curlid)) x2->pcur++;
				}
			      } else {
				register DPS_STACK_ITEM *t = x1;
				x1 = x2; x2 = t; flag1 = !flag1;
			      }
			    }
			  }
			}
			DpsStackItemFree(x1); DpsStackItemFree(x2);
			res.count = res.pcur - res.pbegin;
#ifdef DEBUG_BOOL
			DpsLog(query, DPS_LOG_EXTRA, "Perform {%d} ANYWORD {%d} - > %d", 
			       (x1) ? x1->count : -1, (x2) ? x2->count : -1, res.count);
#endif
			rc = PUSHARG(s, &res);
			break;
		case DPS_STACK_AND:
			x1 = POPARG(s);
			x2 = POPARG(s);
			if (x2 == NULL || x1 == NULL) {
			  if (x1 != NULL) { res = *x1; x1 = NULL; }
			  if (x2 != NULL) { res = *x2; x2 = NULL; }
			} else {
			  res.order_from = (x1->order_from <= x2->order_from) ? x1->order_from : x2->order_from;
			  res.order_to = (x1->order_to >= x2->order_to) ? x1->order_to : x2->order_to;
			  if ((x1->origin & DPS_WORD_ORIGIN_STOP) && (x2->origin & DPS_WORD_ORIGIN_STOP) ) {
			    if (DPS_OK != proceedOR(query, &res, x1, x2)) return DPS_ERROR;
			    res.origin = DPS_WORD_ORIGIN_STOP;
			  } else if (x2->origin & DPS_WORD_ORIGIN_STOP) {
			    if (DPS_OK != proceedSTOP(query, &res, x1, x2)) return DPS_ERROR;
			  } else if (x1->origin & DPS_WORD_ORIGIN_STOP ) {
			    if (DPS_OK != proceedSTOP(query, &res, x2, x1)) return DPS_ERROR;
			  } else if (!((x1->cmd & DPS_STACK_WORD_NOT) && (x2->cmd & DPS_STACK_WORD_NOT))) {
			    res.pbegin = res.pcur = (DPS_URL_CRD_DB*)DpsMalloc((x1->count + x2->count + 1) * sizeof(DPS_URL_CRD_DB));
			    if (res.pbegin == NULL) return DPS_ERROR;
			    x1->pcur = x1->pbegin; x1->plast = x1->pbegin + x1->count;
			    x2->pcur = x2->pbegin; x2->plast = x2->pbegin + x2->count;
			    if (x1->cmd & DPS_STACK_WORD_NOT) {
			      register DPS_STACK_ITEM *t = x1;
			      x1 = x2; x2 = t;
			    }
			    if (x2->cmd & DPS_STACK_WORD_NOT) {
			      while (x1->pcur < x1->plast && x2->pcur < x2->plast) {
				while ((x1->pcur < x1->plast) && (x1->pcur->url_id < x2->pcur->url_id)) {
				  *res.pcur = *x1->pcur;
				  res.pcur++; x1->pcur++;
				}
				while ((x2->pcur < x2->plast) && (x2->pcur->url_id < x1->pcur->url_id)) x2->pcur++;
			    
				if (x2->pcur->url_id == x1->pcur->url_id) {
				  register urlid_t curlid = x1->pcur->url_id;
				  while ((x1->pcur < x1->plast) && (x1->pcur->url_id == curlid)) x1->pcur++;
				  while ((x2->pcur < x2->plast) && (x2->pcur->url_id == curlid)) x2->pcur++;
				}
			      }
			      while (x1->pcur < x1->plast) {
				*res.pcur = *x1->pcur;
				res.pcur++; x1->pcur++;
			      }
			    } else {
#if 0
			      {
				DPS_URL_CRD_DB *w;
				for (w = x1->pcur; w < x1->plast; w++) {
				  fprintf(stderr, "x1.url_id:%d  .coord:%d\n", w->url_id, w->coord);
				}
				for (w = x2->pcur; w < x2->plast; w++) {
				  fprintf(stderr, "x2.url_id:%d  .coord:%d\n", w->url_id, w->coord);
				}
			      }
#endif

			      while (x1->pcur < x1->plast && x2->pcur < x2->plast) {
				while ((x2->pcur < x2->plast) && (x2->pcur->url_id < x1->pcur->url_id)) x2->pcur++;
				if (x2->pcur >= x2->plast) break;
				if (x2->pcur->url_id == x1->pcur->url_id) {
				  register urlid_t curlid = x1->pcur->url_id;
				  while ((x1->pcur < x1->plast) && (x2->pcur < x2->plast) && (x1->pcur->url_id == x2->pcur->url_id)) {
				    if (x1->pcur->coord <= x2->pcur->coord) {
				      *res.pcur = *x1->pcur;
				      res.pcur++; x1->pcur++;
				    } else {
				      *res.pcur = *x2->pcur;
				      res.pcur++; x2->pcur++;
				    }
				  }
				  while ((x1->pcur < x1->plast) && (x1->pcur->url_id == curlid)) {
				    *res.pcur = *x1->pcur;
				    res.pcur++; x1->pcur++;
				  }
				  while ((x2->pcur < x2->plast) && (x2->pcur->url_id == curlid)) {
				    *res.pcur = *x2->pcur;
				    res.pcur++; x2->pcur++;
				  }
				} else {
				  register DPS_STACK_ITEM *t = x1;
				  x1 = x2; x2 = t;
				}
			      }
			    }
			  }
			}
			DpsStackItemFree(x1); DpsStackItemFree(x2);
			res.count = res.pcur - res.pbegin;
#ifdef DEBUG_BOOL
#if 0
			{
			  DPS_URL_CRD_DB *w = res.pbegin;
			  size_t q;
			  for (q = 0; q < res.count; q++) {
			    fprintf(stderr, "res.url_id:%d  .coord:%d\n", w[q].url_id, w[q].coord);
			  }
			}
#endif
			DpsLog(query, DPS_LOG_EXTRA, "Perform {%d}.%x & {%d}.%x - > {%d}.%x", 
	       (x1) ? x1->count : -1, (x1) ? x1->origin : -1, (x2) ? x2->count : -1 , (x2) ? x2->origin : -1, res.count, res.origin);
/*			printBoolRes(query, &res);*/
			DpsLog(query, DPS_LOG_EXTRA, "===");
#endif
			rc = PUSHARG(s, &res);
			break;
		case DPS_STACK_NOT:
		        x1 = POPARG(s);
			/* res = x1 ? 0 : 1; */
			if (x1 != NULL) {
			  x1->cmd ^= DPS_STACK_WORD_NOT;
			  rc = PUSHARG(s, x1);
			}
#ifdef DEBUG_BOOL
			DpsLog(query, DPS_LOG_EXTRA, "Perform ~ {%d}", (x1) ? x1->count : -1);
#endif
			break;
	}
	return rc;
}
示例#4
0
/* Main function to calculate items sequence */
int
UdmCalcBoolItems(UDM_STACK_ITEM *items, size_t nitems, char *count)
{
  UDM_BOOLSTACK s;
  int res;
  size_t i;

  /* Init stack */
  s.ncstack= 0;
  s.nastack= 0;
  s.mcstack= s.mastack = UDM_MAXSTACK;
  s.cstack= (int*)UdmMalloc(UDM_MAXSTACK * sizeof(int));
  s.astack= (unsigned long*)UdmMalloc(UDM_MAXSTACK * sizeof(unsigned long));

#ifdef DEBUG_BOOL
  for (i= 0; i < nitems; i++)
  {
    fprintf(stderr, "[%d]cmd=%d arg=%d\n", i, items[i].cmd, (int)items[i].arg);
  }
#endif

#ifdef DEBUG_BOOL
  fprintf(stderr,"--------\n");
#endif
  for(i= 0; i < nitems; i++)
  {
    int c;
#ifdef DEBUG_BOOL
    fprintf(stderr,".[%d] %c\n", i, item_type(items[i].cmd, items[i].arg));
#endif
    switch((c= items[i].cmd))
    {
      case UDM_STACK_RIGHT:
        /* Perform till LEFT bracket */
        while((TOPCMD(&s)!=UDM_STACK_LEFT)&&(TOPCMD(&s)!=UDM_STACK_BOT))
          perform(&s,POPCMD(&s));
        /* Pop LEFT bracket itself */
        if(TOPCMD(&s)==UDM_STACK_LEFT)
          POPCMD(&s);
        break;
      case UDM_STACK_OR:
      case UDM_STACK_AND:
        while(c<=TOPCMD(&s))
          perform(&s,POPCMD(&s));
        /* IMPORTANT! No break here! That's OK*/
        /* Так надо ! */
      case UDM_STACK_LEFT:
      case UDM_STACK_NOT:
        PUSHCMD(&s,c);
        break;
      case UDM_STACK_PHRASE:
        PUSHARG(&s, (count[items[i+1].arg]) ? 1UL : 0UL);
        for (i++; items[i].cmd != UDM_STACK_PHRASE; i++)
#ifdef DEBUG_BOOL
    fprintf(stderr,"[%d] %c\n", i, item_type(items[i].cmd, count[items[i].arg]));
    fprintf(stderr,"[%d] %c\n", i, item_type(items[i].cmd, count[items[i].arg]));
#endif
        ;
        break;
      case UDM_STACK_STOP:
        PUSHARG(&s, 1UL);
        break;
      case UDM_STACK_WORD:
        PUSHARG(&s, (count[items[i].arg]) ? 1UL : 0UL);
        break;
      default:
        UDM_ASSERT(0);
    }
  }
  while(TOPCMD(&s) != UDM_STACK_BOT)
    perform(&s, POPCMD(&s));

  res= POPARG(&s);
  UDM_FREE(s.cstack);
  UDM_FREE(s.astack);
#ifdef DEBUG_BOOL
  fprintf(stderr, "result: %d\n", res);
#endif
  return res;
}