static void S_balance_parens(QueryParser *self, Vector *elems) { UNUSED_VAR(self); // Count paren balance, eliminate unbalanced right parens. int64_t paren_depth = 0; size_t i = 0; while (i < Vec_Get_Size(elems)) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i); if (ParserElem_Get_Type(elem) == TOKEN_OPEN_PAREN) { paren_depth++; } else if (ParserElem_Get_Type(elem) == TOKEN_CLOSE_PAREN) { if (paren_depth > 0) { paren_depth--; } else { Vec_Excise(elems, i, 1); continue; } } i++; } // Insert implicit parens. while (paren_depth--) { ParserElem *elem = ParserElem_new(TOKEN_CLOSE_PAREN, NULL); Vec_Push(elems, (Obj*)elem); } }
static void S_discard_elems(Vector *elems, uint32_t type) { for (size_t i = Vec_Get_Size(elems); i--;) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i); if (ParserElem_Get_Type(elem) == type) { Vec_Excise(elems, i, 1); } } }
Vector* HeatMap_Flatten_Spans_IMP(HeatMap *self, Vector *spans) { const size_t num_spans = Vec_Get_Size(spans); UNUSED_VAR(self); if (!num_spans) { return Vec_new(0); } else { Vector *flattened = S_flattened_but_empty_spans(spans); const size_t num_raw_flattened = Vec_Get_Size(flattened); // Iterate over each of the source spans, contributing their scores to // any destination span that falls within range. size_t dest_tick = 0; for (size_t i = 0; i < num_spans; i++) { Span *source_span = (Span*)Vec_Fetch(spans, i); int32_t source_span_offset = Span_Get_Offset(source_span); int32_t source_span_len = Span_Get_Length(source_span); int32_t source_span_end = source_span_offset + source_span_len; // Get the location of the flattened span that shares the source // span's offset. for (; dest_tick < num_raw_flattened; dest_tick++) { Span *dest_span = (Span*)Vec_Fetch(flattened, dest_tick); if (Span_Get_Offset(dest_span) == source_span_offset) { break; } } // Fill in scores. for (size_t j = dest_tick; j < num_raw_flattened; j++) { Span *dest_span = (Span*)Vec_Fetch(flattened, j); if (Span_Get_Offset(dest_span) == source_span_end) { break; } else { float new_weight = Span_Get_Weight(dest_span) + Span_Get_Weight(source_span); Span_Set_Weight(dest_span, new_weight); } } } // Leave holes instead of spans that don't have any score. dest_tick = 0; for (size_t i = 0; i < num_raw_flattened; i++) { Span *span = (Span*)Vec_Fetch(flattened, i); if (Span_Get_Weight(span)) { Vec_Store(flattened, dest_tick++, INCREF(span)); } } Vec_Excise(flattened, dest_tick, num_raw_flattened - dest_tick); return flattened; } }
static void S_parse_subqueries(QueryParser *self, Vector *elems) { const int32_t default_occur = QParser_IVARS(self)->default_occur; while (1) { // Work from the inside out, starting with the leftmost innermost // paren group. size_t left = SIZE_MAX; size_t right = SIZE_MAX; String *field = NULL; for (size_t i = 0, max = Vec_Get_Size(elems); i < max; i++) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i); uint32_t type = ParserElem_Get_Type(elem); if (type == TOKEN_OPEN_PAREN) { left = i; } else if (type == TOKEN_CLOSE_PAREN) { right = i; break; } else if (type == TOKEN_FIELD && i < max - 1) { // If a field applies to an enclosing paren, pass it along. ParserElem *next_elem = (ParserElem*)Vec_Fetch(elems, i + 1); uint32_t next_type = ParserElem_Get_Type(next_elem); if (next_type == TOKEN_OPEN_PAREN) { field = (String*)ParserElem_As(elem, STRING); } } } // Break out of loop when there are no parens left. if (right == SIZE_MAX) { break; } // Create the subquery. Vector *sub_elems = Vec_Slice(elems, left + 1, right - left - 1); Query *subquery = S_parse_subquery(self, sub_elems, field, true); ParserElem *new_elem = ParserElem_new(TOKEN_QUERY, (Obj*)subquery); if (default_occur == MUST) { ParserElem_Require(new_elem); } DECREF(sub_elems); // Replace the elements used to create the subquery with the subquery // itself. if (left > 0) { ParserElem *maybe_field = (ParserElem*)Vec_Fetch(elems, left - 1); uint32_t maybe_field_type = ParserElem_Get_Type(maybe_field); if (maybe_field_type == TOKEN_FIELD) { left -= 1; } } Vec_Excise(elems, left + 1, right - left); Vec_Store(elems, left, (Obj*)new_elem); } }
static void S_compose_or_queries(QueryParser *self, Vector *elems) { const int32_t default_occur = QParser_IVARS(self)->default_occur; for (uint32_t i = 0; i + 2 < Vec_Get_Size(elems); i++) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i + 1); if (ParserElem_Get_Type(elem) == TOKEN_OR) { ParserElem *preceding = (ParserElem*)Vec_Fetch(elems, i); Vector *children = Vec_new(2); uint32_t num_to_zap = 0; // Add first clause. Query *preceding_query = (Query*)ParserElem_As(preceding, QUERY); Vec_Push(children, INCREF(preceding_query)); // Add following clauses. for (uint32_t j = i + 1, jmax = Vec_Get_Size(elems); j < jmax; j += 2, num_to_zap += 2 ) { ParserElem *maybe_or = (ParserElem*)Vec_Fetch(elems, j); ParserElem *following = (ParserElem*)Vec_Fetch(elems, j + 1); if (ParserElem_Get_Type(maybe_or) != TOKEN_OR) { break; } else if (ParserElem_Get_Type(following) == TOKEN_QUERY) { Query *next = (Query*)ParserElem_As(following, QUERY); Vec_Push(children, INCREF(next)); } else { THROW(ERR, "Unexpected type: %u32", ParserElem_Get_Type(following)); } } Query *or_query = QParser_Make_OR_Query(self, children); ParserElem_Set_Value(preceding, (Obj*)or_query); if (default_occur == MUST) { ParserElem_Require(preceding); } DECREF(or_query); DECREF(children); Vec_Excise(elems, i + 1, num_to_zap); } } }
static void S_refill_buffer(SortExternal *self, SortExternalIVARS *ivars) { // Reset buffer vars. SortEx_Clear_Buffer(self); // Make sure all runs have at least one item in the buffer. uint32_t i = 0; while (i < Vec_Get_Size(ivars->runs)) { SortExternal *const run = (SortExternal*)Vec_Fetch(ivars->runs, i); if (SortEx_Buffer_Count(run) > 0 || SortEx_Refill(run) > 0) { i++; // Run has some elements, so keep. } else { Vec_Excise(ivars->runs, i, 1); } } // Absorb as many elems as possible from all runs into main buffer. if (Vec_Get_Size(ivars->runs)) { Obj **endpost = S_find_endpost(self, ivars); S_absorb_slices(self, ivars, endpost); } }
static void S_winnow_boolops(QueryParser *self, Vector *elems) { UNUSED_VAR(self); for (uint32_t i = 0; i < Vec_Get_Size(elems); i++) { ParserElem *elem = (ParserElem*)Vec_Fetch(elems, i); if (ParserElem_Get_Type(elem) != TOKEN_QUERY) { uint32_t num_to_zap = 0; ParserElem *preceding = (ParserElem*)Vec_Fetch(elems, i - 1); ParserElem *following = (ParserElem*)Vec_Fetch(elems, i + 1); if (!preceding || ParserElem_Get_Type(preceding) != TOKEN_QUERY) { num_to_zap = 1; } if (!following || ParserElem_Get_Type(following) != TOKEN_QUERY) { num_to_zap = 1; } for (uint32_t j = i + 1, jmax = Vec_Get_Size(elems); j < jmax; j++) { ParserElem *maybe = (ParserElem*)Vec_Fetch(elems, j); if (ParserElem_Get_Type(maybe) == TOKEN_QUERY) { break; } else { num_to_zap++; } } if (num_to_zap) { Vec_Excise(elems, i, num_to_zap); } } } }
static Query* S_parse_subquery(QueryParser *self, Vector *elems, String *default_field, bool enclosed) { if (Vec_Get_Size(elems)) { ParserElem *first = (ParserElem*)Vec_Fetch(elems, 0); if (ParserElem_Get_Type(first) == TOKEN_OPEN_PAREN) { enclosed = true; Vec_Excise(elems, 0, 1); DECREF(Vec_Pop(elems)); } } S_compose_inner_queries(self, elems, default_field); S_discard_elems(elems, TOKEN_FIELD); S_discard_elems(elems, TOKEN_STRING); S_apply_plusses_and_negations(self, elems); S_discard_elems(elems, TOKEN_PLUS); S_discard_elems(elems, TOKEN_MINUS); S_discard_elems(elems, TOKEN_NOT); S_compose_not_queries(self, elems); S_winnow_boolops(self, elems); if (Vec_Get_Size(elems) > 2) { S_compose_and_queries(self, elems); // Don't double wrap '(a AND b)'. if (Vec_Get_Size(elems) == 1) { enclosed = false; } } S_discard_elems(elems, TOKEN_AND); if (Vec_Get_Size(elems) > 2) { S_compose_or_queries(self, elems); // Don't double wrap '(a OR b)'. if (Vec_Get_Size(elems) == 1) { enclosed = false; } } S_discard_elems(elems, TOKEN_OR); Query *retval = S_compose_subquery(self, elems, enclosed); return retval; }