/* 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); }
/* 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; }
/* 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; }
/* 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; }