Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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);
}