static void pullup_submit_field(PullupContext *s, PullupBuffer *b, int parity) { PullupField *f; /* Grow the circular list if needed */ if (check_field_queue(s) < 0) return; /* Cannot have two fields of same parity in a row; drop the new one */ if (s->last && s->last->parity == parity) return; f = s->head; f->parity = parity; f->buffer = pullup_lock_buffer(b, parity); f->flags = 0; f->breaks = 0; f->affinity = 0; compute_metric(s, f->diffs, f, parity, f->prev->prev, parity, s->diff); compute_metric(s, f->combs, parity ? f->prev : f, 0, parity ? f : f->prev, 1, s->comb); compute_metric(s, f->vars, f, parity, f, -1, s->var); emms_c(); /* Advance the circular list */ if (!s->first) s->first = s->head; s->last = s->head; s->head = s->head->next; }
Datum internal_get_array_of_close_canopies(PG_FUNCTION_ARGS) { SvecType *svec; Datum *all_canopies; int num_all_canopies; float8 threshold; PGFunction metric_fn; ArrayType *close_canopies_arr; int4 *close_canopies; int num_close_canopies; size_t bytes; MemoryContext mem_context_for_function_calls; svec = PG_GETARG_SVECTYPE_P(verify_arg_nonnull(fcinfo, 0)); get_svec_array_elms(PG_GETARG_ARRAYTYPE_P(verify_arg_nonnull(fcinfo, 1)), &all_canopies, &num_all_canopies); threshold = PG_GETARG_FLOAT8(verify_arg_nonnull(fcinfo, 2)); metric_fn = get_metric_fn(PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 3))); mem_context_for_function_calls = setup_mem_context_for_functional_calls(); close_canopies = (int4 *) palloc(sizeof(int4) * num_all_canopies); num_close_canopies = 0; for (int i = 0; i < num_all_canopies; i++) { if (compute_metric(metric_fn, mem_context_for_function_calls, PointerGetDatum(svec), all_canopies[i]) < threshold) close_canopies[num_close_canopies++] = i + 1 /* lower bound */; } MemoryContextDelete(mem_context_for_function_calls); /* If we cannot find any close canopy, return NULL. Note that the result * we return will be passed to internal_kmeans_closest_centroid() and if the * array of close canopies is NULL, then internal_kmeans_closest_centroid() * will consider and compute the distance to all centroids. */ if (num_close_canopies == 0) PG_RETURN_NULL(); bytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int4) * num_close_canopies; close_canopies_arr = (ArrayType *) palloc0(bytes); SET_VARSIZE(close_canopies_arr, bytes); ARR_ELEMTYPE(close_canopies_arr) = INT4OID; ARR_NDIM(close_canopies_arr) = 1; ARR_DIMS(close_canopies_arr)[0] = num_close_canopies; ARR_LBOUND(close_canopies_arr)[0] = 1; memcpy(ARR_DATA_PTR(close_canopies_arr), close_canopies, sizeof(int4) * num_close_canopies); PG_RETURN_ARRAYTYPE_P(close_canopies_arr); }
Datum internal_remove_close_canopies(PG_FUNCTION_ARGS) { ArrayType *all_canopies_arr; Datum *all_canopies; int num_all_canopies; PGFunction metric_fn; float8 threshold; Datum *close_canopies; int num_close_canopies; bool addIndexI; MemoryContext mem_context_for_function_calls; all_canopies_arr = PG_GETARG_ARRAYTYPE_P(verify_arg_nonnull(fcinfo, 0)); get_svec_array_elms(all_canopies_arr, &all_canopies, &num_all_canopies); metric_fn = get_metric_fn(PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 1))); threshold = PG_GETARG_FLOAT8(verify_arg_nonnull(fcinfo, 2)); mem_context_for_function_calls = setup_mem_context_for_functional_calls(); close_canopies = (Datum *) palloc(sizeof(Datum) * num_all_canopies); num_close_canopies = 0; for (int i = 0; i < num_all_canopies; i++) { addIndexI = true; for (int j = 0; j < num_close_canopies; j++) { if (compute_metric(metric_fn, mem_context_for_function_calls, all_canopies[i], close_canopies[j]) < threshold) { addIndexI = false; break; } } if (addIndexI) close_canopies[num_close_canopies++] = all_canopies[i]; } MemoryContextDelete(mem_context_for_function_calls); PG_RETURN_ARRAYTYPE_P( construct_array( close_canopies, /* elems */ num_close_canopies, /* nelems */ ARR_ELEMTYPE(all_canopies_arr), /* elmtype */ -1, /* elmlen */ false, /* elmbyval */ 'd') /* elmalign */ ); }
Datum internal_kmeans_canopy_transition(PG_FUNCTION_ARGS) { ArrayType *canopies_arr; Datum *canopies; int num_canopies; SvecType *point; PGFunction metric_fn; float8 threshold; MemoryContext mem_context_for_function_calls; canopies_arr = PG_GETARG_ARRAYTYPE_P(verify_arg_nonnull(fcinfo, 0)); get_svec_array_elms(canopies_arr, &canopies, &num_canopies); point = PG_GETARG_SVECTYPE_P(verify_arg_nonnull(fcinfo, 1)); metric_fn = get_metric_fn(PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 2))); threshold = PG_GETARG_FLOAT8(verify_arg_nonnull(fcinfo, 3)); mem_context_for_function_calls = setup_mem_context_for_functional_calls(); for (int i = 0; i < num_canopies; i++) { if (compute_metric(metric_fn, mem_context_for_function_calls, PointerGetDatum(point), canopies[i]) < threshold) PG_RETURN_ARRAYTYPE_P(canopies_arr); } MemoryContextDelete(mem_context_for_function_calls); int idx = (ARR_NDIM(canopies_arr) == 0) ? 1 : ARR_LBOUND(canopies_arr)[0] + ARR_DIMS(canopies_arr)[0]; return PointerGetDatum( array_set( canopies_arr, /* array: the initial array object (mustn't be NULL) */ 1, /* nSubscripts: number of subscripts supplied */ &idx, /* indx[]: the subscript values */ PointerGetDatum(point), /* dataValue: the datum to be inserted at the given position */ false, /* isNull: whether dataValue is NULL */ -1, /* arraytyplen: pg_type.typlen for the array type */ -1, /* elmlen: pg_type.typlen for the array's element type */ false, /* elmbyval: pg_type.typbyval for the array's element type */ 'd') /* elmalign: pg_type.typalign for the array's element type */ ); }