/*********************************************** !!!! DO NOT EDIT THIS FILE !!!! This file was auto-generated by Build.PL from lib/KinoSearch/Index/MultiTermDocs.pm See KinoSearch::Docs::DevGuide for details. ***********************************************/ #line 135 "lib/KinoSearch/Index/MultiTermDocs.pm" #include "KinoSearchIndexMultiTermDocs.h" void Kino_MultiTermDocs_init_child(TermDocs* term_docs, SV *sub_term_docs_avref, AV *starts_av) { MultiTermDocsChild *child; I32 i; SV **sv_ptr; AV *sub_term_docs_av; /* allocate */ Kino_New(0, child, 1, MultiTermDocsChild); term_docs->child = child; /* assign */ child->current = NULL; child->base = 0; child->pointer = 0; /* extract AV* and take stock of how many sub-TermDocs we've got */ child->sub_term_docs_avref = newSVsv(sub_term_docs_avref);; sub_term_docs_av = (AV*)SvRV(sub_term_docs_avref); child->num_subs = av_len(sub_term_docs_av) + 1; /* extract starts from starts array, subTermDocs from the subs array */ Kino_New(0, child->starts, child->num_subs, U32); Kino_New(0, child->sub_term_docs, child->num_subs, TermDocs*); for (i = 0; i < child->num_subs; i++) { sv_ptr = av_fetch(starts_av, i, 0); if (sv_ptr == NULL) Kino_confess("starts array doesn't have enough valid members"); child->starts[i] = (U32)SvUV(*sv_ptr); sv_ptr = av_fetch(sub_term_docs_av, i, 0); if (sv_ptr == NULL) Kino_confess("TermDocs array doesn't have enough valid members"); Kino_extract_struct(*sv_ptr, child->sub_term_docs[i], TermDocs*, "KinoSearch::Index::TermDocs"); } /* assign method pointers */ term_docs->set_doc_freq = Kino_MultiTermDocs_set_doc_freq_death; term_docs->get_doc_freq = Kino_MultiTermDocs_get_doc_freq; term_docs->get_doc = Kino_MultiTermDocs_get_doc; term_docs->get_freq = Kino_MultiTermDocs_get_freq; term_docs->get_positions = Kino_MultiTermDocs_get_positions; term_docs->bulk_read = Kino_MultiTermDocs_bulk_read; term_docs->next = Kino_MultiTermDocs_next; term_docs->skip_to = Kino_MultiTermDocs_skip_to; term_docs->destroy = Kino_MultiTermDocs_destroy; } void Kino_MultiTermDocs_set_doc_freq_death(TermDocs *term_docs, U32 doc_freq) { Kino_confess("can't set doc_freq on a MultiTermDocs"); } U32 Kino_MultiTermDocs_get_doc_freq(TermDocs *term_docs) { MultiTermDocsChild *child; TermDocs *sub_td; I32 i; U32 doc_freq = 0; /* sum the doc_freqs of all segments */ child = (MultiTermDocsChild*)term_docs->child; for (i = 0; i < child->num_subs; i++) { sub_td = child->sub_term_docs[i]; doc_freq += sub_td->get_doc_freq(sub_td); } return doc_freq; } U32 Kino_MultiTermDocs_get_doc(TermDocs *term_docs) { MultiTermDocsChild *child; child = (MultiTermDocsChild*)term_docs->child; if (child->current == NULL) return KINO_TERM_DOCS_SENTINEL; return child->current->get_doc(child->current) + child->base; } U32 Kino_MultiTermDocs_get_freq(TermDocs *term_docs) { MultiTermDocsChild *child; child = (MultiTermDocsChild*)term_docs->child; if (child->current == NULL) return KINO_TERM_DOCS_SENTINEL; return child->current->get_freq(child->current); } SV* Kino_MultiTermDocs_get_positions(TermDocs *term_docs) { MultiTermDocsChild *child; child = (MultiTermDocsChild*)term_docs->child; if (child->current == NULL) return &PL_sv_undef; return child->current->get_positions(child->current); } U32 Kino_MultiTermDocs_bulk_read(TermDocs *term_docs, SV *doc_nums_sv, SV *freqs_sv, U32 num_wanted) { MultiTermDocsChild *child; U32 i, num_got, base; U32 *doc_nums; child = (MultiTermDocsChild*)term_docs->child; while (1) { /* move to the next SegTermDocs */ while (child->current == NULL) { if (child->pointer < child->num_subs) { child->base = child->starts[ child->pointer ]; child->current = child->sub_term_docs[ child->pointer ]; child->pointer++; } else { return 0; } } num_got = child->current->bulk_read( child->current, doc_nums_sv, freqs_sv, num_wanted ); if (num_got == 0) { /* no more docs left in this segment */ child->current = NULL; } else { /* add the start offset for this seg to each doc */ base = child->base; doc_nums = (U32*)SvPVX(doc_nums_sv); for (i = 0; i < num_got; i++) { *doc_nums++ += base; } return num_got; } } } bool Kino_MultiTermDocs_next(TermDocs* term_docs) { MultiTermDocsChild *child; child = (MultiTermDocsChild*)term_docs->child; if ( child->current != NULL && child->current->next(child->current) ) { return 1; } else if (child->pointer < child->num_subs) { /* try next segment */ child->base = child->starts[ child->pointer ]; child->current = child->sub_term_docs[ child->pointer ]; child->pointer++; return term_docs->next(term_docs); /* recurse */ } else { /* done with all segments */ return 0; } } bool Kino_MultiTermDocs_skip_to(TermDocs *term_docs, U32 target) { MultiTermDocsChild *child = (MultiTermDocsChild*)term_docs->child; if ( child->current != NULL && child->current->skip_to(child->current, (target - child->base)) ) { return TRUE; } else if (child->pointer < child->num_subs) { /* try next segment */ child->base = child->starts[ child->pointer ]; child->current = child->sub_term_docs[ child->pointer ]; child->pointer++; return term_docs->skip_to(term_docs, target); /* recurse */ } else { return FALSE; } } void Kino_MultiTermDocs_destroy(TermDocs* term_docs) { MultiTermDocsChild *child; child = (MultiTermDocsChild*)term_docs->child; SvREFCNT_dec(child->sub_term_docs_avref); Kino_Safefree(child->sub_term_docs); Kino_Safefree(child->starts); Kino_Safefree(child); Kino_TermDocs_destroy(term_docs); }