_export void dsp_node_delete(struct dsp_node_t *node) { unsigned int i; for(i = 0; i < node->incnt; i++) sink_delete(node->sink[i]); for(i = 0; i < node->outcnt; i++) source_delete(node->source[i]); mem_free(node->sink); mem_free(node->source); mem_free(node); }
_export void dsp_node_resize(struct dsp_node_t *node, unsigned int incnt, unsigned int outcnt) { unsigned int i; for(i = incnt; i < node->incnt; i++) sink_delete(node->sink[i]); for(i = outcnt; i < node->outcnt; i++) source_delete(node->source[i]); node->sink = mem_realloc(node->sink, incnt * sizeof(void *)); node->source = mem_realloc(node->source, outcnt * sizeof(void *)); for(i = node->incnt; i < incnt; i++) node->sink[i] = sink_new(node); for(i = node->outcnt; i < outcnt; i++) node->source[i] = source_new(node); node->incnt = incnt; node->outcnt = outcnt; }
enum search_ret impact_ord_eval(struct index *idx, struct query *query, struct chash *accumulators, unsigned int acc_limit, struct alloc *alloc, unsigned int mem) { double norm_B; unsigned int i, terms = 0, blockfine, blocks_read, postings_read = 0, postings = 0, bytes = 0, bytes_read = 0; struct term_data *term, *largest; struct disksrc *dsrc; if (query->terms == 0) { /* no terms to process */ return SEARCH_OK; /* allocate space for array */ } else if (!(term = malloc(sizeof(*term) * query->terms))) { return SEARCH_ENOMEM; } /* sort by selectivity (by inverse t_f) */ qsort(query->term, query->terms, sizeof(*query->term), f_t_cmp); norm_B = pow(idx->impact_stats.w_qt_max / idx->impact_stats.w_qt_min, idx->impact_stats.w_qt_min / (idx->impact_stats.w_qt_max - idx->impact_stats.w_qt_min)); /* initialise data for each query term */ for (i = 0; i < query->terms; i++) { unsigned int termfine; double w_qt; /* initialise src/vec for term */ term[i].v.pos = term[i].v.end = NULL; term[i].src = NULL; w_qt = (1 + log(query->term[i].f_qt)) * log(1 + (idx->impact_stats.avg_f_t / query->term[i].f_t)); w_qt = impact_normalise(w_qt, norm_B, idx->impact_stats.slope, idx->impact_stats.w_qt_max, idx->impact_stats.w_qt_min); term[i].w_qt = impact_quantise(w_qt, idx->impact_stats.quant_bits, idx->impact_stats.w_qt_max, idx->impact_stats.w_qt_min); /* apply term fine to term impact */ termfine = (i < 2) ? 0 : i - 2; if (termfine < term[i].w_qt) { term[i].w_qt -= termfine; /* initialise to highest impact, so we'll select and initialise this * term before real processing */ term[i].impact = INT_MAX; terms++; } else { /* we won't use this term */ term[i].w_qt = 0; term[i].impact = 0; } term[i].blocksize = 0; /* XXX */ postings += query->term[i].f_t; bytes += query->term[i].term.vocab.size; } /* get sources for each term (do this in a seperate loop so we've already * excluded lists that we won't use) */ for (i = 0; i < terms; i++) { unsigned int memsize = mem / (terms - i); if (memsize > query->term[i].term.vocab.size) { memsize = query->term[i].term.vocab.size; } if (!(term[i].src = search_term_src(idx, &query->term[i].term, alloc, memsize))) { source_delete(term, terms); free(term); return SEARCH_EINVAL; } mem -= memsize; } blockfine = blocks_read = 0; heap_heapify(term, terms, sizeof(*term), term_data_cmp); do { largest = heap_pop(term, &terms, sizeof(*term), term_data_cmp); if (largest && (largest->impact > blockfine)) { postings_read += largest->blocksize; if (chash_size(accumulators) < acc_limit) { /* reserve enough memory for accumulators and decode */ if (chash_reserve(accumulators, largest->blocksize) >= largest->blocksize) { impact_decode_block(accumulators, largest, blockfine); } else { assert(!CRASH); ERROR("impact_ord_eval()"); source_delete(term, terms); free(term); return SEARCH_EINVAL; } } else { impact_decode_block_and(accumulators, largest, blockfine); } if (VEC_LEN(&largest->v) < 2 * VEC_VBYTE_MAX) { /* need to read more data */ unsigned int bytes; enum search_ret sret; if ((sret = largest->src->readlist(largest->src, VEC_LEN(&largest->v), (void **) &largest->v.pos, &bytes)) == SEARCH_OK) { /* read succeeded */ largest->v.end = largest->v.pos + bytes; } else if (sret == SEARCH_FINISH) { if (VEC_LEN(&largest->v) || largest->blocksize) { /* didn't finish properly */ assert(!CRASH); ERROR("impact_ord_eval()"); source_delete(term, terms); free(term); return SEARCH_EINVAL; } /* otherwise it will be finished below */ } else { assert(!CRASH); ERROR("impact_ord_eval()"); source_delete(term, terms); free(term); return sret; } } if (!largest->blocksize) { /* need to read the start of the next block */ unsigned long int tmp_bsize, tmp_impact; if (vec_vbyte_read(&largest->v, &tmp_bsize) && (vec_vbyte_read(&largest->v, &tmp_impact) /* second read failed, rewind past first vbyte */ || ((largest->v.pos -= vec_vbyte_len(tmp_bsize)), 0))) { blocks_read++; if (blocks_read > terms) { blockfine++; } largest->blocksize = tmp_bsize; largest->impact = (tmp_impact + 1) * largest->w_qt; largest->docno = -1; heap_insert(term, &terms, sizeof(*term), term_data_cmp, largest); } else if (!VEC_LEN(&largest->v)) { /* finished, don't put back on the heap */ dsrc = (void *) largest->src; bytes_read += dsrc->pos; largest->src->delet(largest->src); largest->src = NULL; } else if (largest->impact != INT_MAX) { /* ensure that this vector is chosen next, as we need the * next impact score */ largest->impact = INT_MAX; assert(largest->blocksize == 0); heap_insert(term, &terms, sizeof(*term), term_data_cmp, largest); } else { /* huh? */ assert(!CRASH); ERROR("impact_ord_eval()"); source_delete(term, terms); free(term); return SEARCH_EINVAL; } } else { heap_insert(term, &terms, sizeof(*term), term_data_cmp, largest); } } } while (largest && (largest->impact > blockfine)); for (i = 0; i < terms; i++) { dsrc = (void *) term[i].src; bytes_read += dsrc->pos; } if (largest) { largest->src->delet(largest->src); largest->src = NULL; } /* end of ranking */ source_delete(term, terms); free(term); return SEARCH_OK; }