Vector* PolyCompiler_Highlight_Spans_IMP(PolyCompiler *self, Searcher *searcher, DocVector *doc_vec, String *field) { PolyCompilerIVARS *const ivars = PolyCompiler_IVARS(self); Vector *spans = Vec_new(0); for (size_t i = 0, max = Vec_Get_Size(ivars->children); i < max; i++) { Compiler *child = (Compiler*)Vec_Fetch(ivars->children, i); Vector *child_spans = Compiler_Highlight_Spans(child, searcher, doc_vec, field); if (child_spans) { Vec_Push_All(spans, child_spans); DECREF(child_spans); } } return spans; }
HeatMap* HeatMap_init(HeatMap *self, Vector *spans, uint32_t window) { HeatMapIVARS *const ivars = HeatMap_IVARS(self); Vector *spans_copy = Vec_Clone(spans); Vector *spans_plus_boosts; ivars->spans = NULL; ivars->window = window; Vec_Sort(spans_copy); spans_plus_boosts = HeatMap_Generate_Proximity_Boosts(self, spans_copy); Vec_Push_All(spans_plus_boosts, spans_copy); Vec_Sort(spans_plus_boosts); ivars->spans = HeatMap_Flatten_Spans(self, spans_plus_boosts); DECREF(spans_plus_boosts); DECREF(spans_copy); return self; }
static Query* S_compose_subquery(QueryParser *self, Vector *elems, bool enclosed) { const int32_t default_occur = QParser_IVARS(self)->default_occur; Query *retval; if (Vec_Get_Size(elems) == 0) { // No elems means no query. Maybe the search string was something // like 'NOT AND' if (enclosed) { retval = default_occur == SHOULD ? QParser_Make_OR_Query(self, NULL) : QParser_Make_AND_Query(self, NULL); } else { retval = (Query*)NoMatchQuery_new(); } } else if (Vec_Get_Size(elems) == 1 && !enclosed) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, 0); Query *query = (Query*)ParserElem_As(elem, QUERY); retval = (Query*)INCREF(query); } else { uint32_t num_elems = Vec_Get_Size(elems); Vector *required = Vec_new(num_elems); Vector *optional = Vec_new(num_elems); Vector *negated = Vec_new(num_elems); Query *req_query = NULL; Query *opt_query = NULL; // Demux elems into bins. for (uint32_t i = 0; i < num_elems; i++) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i); if (ParserElem_Required(elem)) { Vec_Push(required, INCREF(ParserElem_As(elem, QUERY))); } else if (ParserElem_Optional(elem)) { Vec_Push(optional, INCREF(ParserElem_As(elem, QUERY))); } else if (ParserElem_Negated(elem)) { Vec_Push(negated, INCREF(ParserElem_As(elem, QUERY))); } } uint32_t num_required = Vec_Get_Size(required); uint32_t num_negated = Vec_Get_Size(negated); uint32_t num_optional = Vec_Get_Size(optional); // Bind all mandatory matchers together in one Query. if (num_required || num_negated) { if (enclosed || num_required + num_negated > 1) { Vector *children = Vec_Clone(required); Vec_Push_All(children, negated); req_query = QParser_Make_AND_Query(self, children); DECREF(children); } else if (num_required) { req_query = (Query*)INCREF(Vec_Fetch(required, 0)); } else if (num_negated) { req_query = (Query*)INCREF(Vec_Fetch(negated, 0)); } } // Bind all optional matchers together in one Query. if (num_optional) { if (!enclosed && num_optional == 1) { opt_query = (Query*)INCREF(Vec_Fetch(optional, 0)); } else { opt_query = QParser_Make_OR_Query(self, optional); } } // Unify required and optional. if (req_query && opt_query) { if (num_required) { // not just negated elems retval = QParser_Make_Req_Opt_Query(self, req_query, opt_query); } else { // req_query has only negated queries. Vector *children = Vec_new(2); Vec_Push(children, INCREF(req_query)); Vec_Push(children, INCREF(opt_query)); retval = QParser_Make_AND_Query(self, children); DECREF(children); } } else if (opt_query) { // Only optional elems. retval = (Query*)INCREF(opt_query); } else if (req_query) { // Only required elems. retval = (Query*)INCREF(req_query); } else { retval = NULL; // kill "uninitialized" compiler warning THROW(ERR, "Unexpected error"); } DECREF(opt_query); DECREF(req_query); DECREF(negated); DECREF(optional); DECREF(required); } return retval; }
static void S_discover_unused(FilePurger *self, Vector **purgables_ptr, Vector **snapshots_ptr) { FilePurgerIVARS *const ivars = FilePurger_IVARS(self); Folder *folder = ivars->folder; DirHandle *dh = Folder_Open_Dir(folder, NULL); if (!dh) { RETHROW(INCREF(Err_get_error())); } Vector *spared = Vec_new(1); Vector *snapshots = Vec_new(1); String *snapfile = NULL; // Start off with the list of files in the current snapshot. if (ivars->snapshot) { Vector *entries = Snapshot_List(ivars->snapshot); Vector *referenced = S_find_all_referenced(folder, entries); Vec_Push_All(spared, referenced); DECREF(entries); DECREF(referenced); snapfile = Snapshot_Get_Path(ivars->snapshot); if (snapfile) { Vec_Push(spared, INCREF(snapfile)); } } Hash *candidates = Hash_new(64); while (DH_Next(dh)) { String *entry = DH_Get_Entry(dh); if (Str_Starts_With_Utf8(entry, "snapshot_", 9) && Str_Ends_With_Utf8(entry, ".json", 5) && (!snapfile || !Str_Equals(entry, (Obj*)snapfile)) ) { Snapshot *snapshot = Snapshot_Read_File(Snapshot_new(), folder, entry); Lock *lock = IxManager_Make_Snapshot_Read_Lock(ivars->manager, entry); Vector *snap_list = Snapshot_List(snapshot); Vector *referenced = S_find_all_referenced(folder, snap_list); // DON'T obtain the lock -- only see whether another // entity holds a lock on the snapshot file. if (lock) { Lock_Clear_Stale(lock); } if (lock && Lock_Is_Locked(lock)) { // The snapshot file is locked, which means someone's using // that version of the index -- protect all of its entries. uint32_t new_size = Vec_Get_Size(spared) + Vec_Get_Size(referenced) + 1; Vec_Grow(spared, new_size); Vec_Push(spared, (Obj*)Str_Clone(entry)); Vec_Push_All(spared, referenced); } else { // No one's using this snapshot, so all of its entries are // candidates for deletion. for (uint32_t i = 0, max = Vec_Get_Size(referenced); i < max; i++) { String *file = (String*)Vec_Fetch(referenced, i); Hash_Store(candidates, file, (Obj*)CFISH_TRUE); } Vec_Push(snapshots, INCREF(snapshot)); } DECREF(referenced); DECREF(snap_list); DECREF(snapshot); DECREF(lock); } DECREF(entry); } DECREF(dh); // Clean up after a dead segment consolidation. S_zap_dead_merge(self, candidates); // Eliminate any current files from the list of files to be purged. for (uint32_t i = 0, max = Vec_Get_Size(spared); i < max; i++) { String *filename = (String*)Vec_Fetch(spared, i); DECREF(Hash_Delete(candidates, filename)); } // Pass back purgables and Snapshots. *purgables_ptr = Hash_Keys(candidates); *snapshots_ptr = snapshots; DECREF(candidates); DECREF(spared); }