PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ gserialized_spgist_picksplit_nd()

PGDLLEXPORT Datum gserialized_spgist_picksplit_nd ( PG_FUNCTION_ARGS  )

Definition at line 313 of file gserialized_spgist_nd.c.

314 {
315  spgPickSplitIn *in = (spgPickSplitIn *)PG_GETARG_POINTER(0);
316  spgPickSplitOut *out = (spgPickSplitOut *)PG_GETARG_POINTER(1);
317  GIDX *box, *centroid;
318  float *lowXs, *highXs;
319  int ndims, maxdims = -1, count[GIDX_MAX_DIM], median, dim, tuple;
320 
321  for (dim = 0; dim < GIDX_MAX_DIM; dim++)
322  count[dim] = 0;
323 
324  lowXs = palloc(sizeof(float) * in->nTuples * GIDX_MAX_DIM),
325  highXs = palloc(sizeof(float) * in->nTuples * GIDX_MAX_DIM);
326 
327  /* Calculate maxdims median of all ND coordinates */
328  for (tuple = 0; tuple < in->nTuples; tuple++)
329  {
330  box = (GIDX *)DatumGetPointer(in->datums[tuple]);
331  ndims = GIDX_NDIMS(box);
332  if (maxdims < ndims)
333  maxdims = ndims;
334  for (dim = 0; dim < ndims; dim++)
335  {
336  /* If the missing dimension was not padded with -+FLT_MAX */
337  if (GIDX_GET_MAX(box, dim) != FLT_MAX)
338  {
339  lowXs[dim * in->nTuples + count[dim]] = GIDX_GET_MIN(box, dim);
340  highXs[dim * in->nTuples + count[dim]] = GIDX_GET_MAX(box, dim);
341  count[dim]++;
342  }
343  }
344  }
345 
346  for (dim = 0; dim < maxdims; dim++)
347  {
348  qsort(&lowXs[dim * in->nTuples], count[dim], sizeof(float), compareFloats);
349  qsort(&highXs[dim * in->nTuples], count[dim], sizeof(float), compareFloats);
350  }
351 
352  centroid = (GIDX *)palloc(GIDX_SIZE(maxdims));
353  SET_VARSIZE(centroid, GIDX_SIZE(maxdims));
354 
355  for (dim = 0; dim < maxdims; dim++)
356  {
357  median = count[dim] / 2;
358  GIDX_SET_MIN(centroid, dim, lowXs[dim * in->nTuples + median]);
359  GIDX_SET_MAX(centroid, dim, highXs[dim * in->nTuples + median]);
360  }
361 
362  /* Fill the output */
363  out->hasPrefix = true;
364  out->prefixDatum = PointerGetDatum(gidx_copy(centroid));
365 
366  out->nNodes = 0x01 << (2 * maxdims);
367  out->nodeLabels = NULL; /* We don't need node labels. */
368 
369  out->mapTuplesToNodes = palloc(sizeof(int) * in->nTuples);
370  out->leafTupleDatums = palloc(sizeof(Datum) * in->nTuples);
371 
372  /*
373  * Assign ranges to corresponding nodes according to octants relative to
374  * the "centroid" range
375  */
376  for (tuple = 0; tuple < in->nTuples; tuple++)
377  {
378  GIDX *box = (GIDX *)DatumGetPointer(in->datums[tuple]);
379  uint16_t octant = getOctant(centroid, box);
380 
381  out->leafTupleDatums[tuple] = PointerGetDatum(box);
382  out->mapTuplesToNodes[tuple] = octant;
383  }
384 
385  pfree(lowXs);
386  pfree(highXs);
387 
388  PG_RETURN_VOID();
389 }
GIDX * gidx_copy(GIDX *b)
static uint16_t getOctant(GIDX *centroid, GIDX *inBox)
static int compareFloats(const void *a, const void *b)
int count
Definition: genraster.py:57
Datum centroid(PG_FUNCTION_ARGS)

References centroid(), compareFloats(), genraster::count, getOctant(), and gidx_copy().

Here is the call graph for this function: