PostGIS  3.0.6dev-r@@SVN_REVISION@@

◆ gserialized_spgist_inner_consistent_nd()

PGDLLEXPORT Datum gserialized_spgist_inner_consistent_nd ( PG_FUNCTION_ARGS  )

Definition at line 396 of file gserialized_spgist_nd.c.

397 {
398  spgInnerConsistentIn *in = (spgInnerConsistentIn *)PG_GETARG_POINTER(0);
399  spgInnerConsistentOut *out = (spgInnerConsistentOut *)PG_GETARG_POINTER(1);
400  MemoryContext old_ctx;
401  CubeGIDX *cube_box;
402  int *nodeNumbers, i, j;
403  void **traversalValues;
404  char gidxmem[GIDX_MAX_SIZE];
405  GIDX *centroid, *query_gbox_index = (GIDX *)gidxmem;
406 
407  POSTGIS_DEBUG(4, "[SPGIST] 'inner consistent' function called");
408 
409  if (in->allTheSame)
410  {
411  /* Report that all nodes should be visited */
412  out->nNodes = in->nNodes;
413  out->nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes);
414  for (i = 0; i < in->nNodes; i++)
415  out->nodeNumbers[i] = i;
416 
417  PG_RETURN_VOID();
418  }
419 
420  /*
421  * We switch memory context, because we want to allocate memory for new
422  * traversal values (next_cube_box) and pass these pieces of memory to
423  * further call of this function.
424  */
425  old_ctx = MemoryContextSwitchTo(in->traversalMemoryContext);
426 
427  centroid = (GIDX *)DatumGetPointer(in->prefixDatum);
428 
429  /*
430  * We are saving the traversal value or initialize it an unbounded one, if
431  * we have just begun to walk the tree.
432  */
433  if (in->traversalValue)
434  cube_box = in->traversalValue;
435  else
436  cube_box = initCubeBox(GIDX_NDIMS(centroid));
437 
438  /* Allocate enough memory for nodes */
439  out->nNodes = 0;
440  nodeNumbers = (int *)palloc(sizeof(int) * in->nNodes);
441  traversalValues = (void **)palloc(sizeof(void *) * in->nNodes);
442 
443  for (i = 0; i < in->nNodes; i++)
444  {
445  CubeGIDX *next_cube_box = nextCubeBox(cube_box, centroid, (uint16_t)i);
446  bool flag = true;
447 
448  for (j = 0; j < in->nkeys; j++)
449  {
450  StrategyNumber strategy = in->scankeys[j].sk_strategy;
451  Datum query = in->scankeys[j].sk_argument;
452 
453  /* Quick sanity check on query argument. */
454  if (DatumGetPointer(query) == NULL)
455  {
456  POSTGIS_DEBUG(4, "[SPGIST] null query pointer (!?!)");
457  flag = false;
458  break;
459  }
460 
461  /* Null box should never make this far. */
462  if (gserialized_datum_get_gidx_p(query, query_gbox_index) == LW_FAILURE)
463  {
464  POSTGIS_DEBUG(4, "[SPGIST] null query_gbox_index!");
465  flag = false;
466  break;
467  }
468 
469  switch (strategy)
470  {
473  flag = overlapND(next_cube_box, query_gbox_index);
474  break;
475 
478  flag = containND(next_cube_box, query_gbox_index);
479  break;
480 
481  default:
482  elog(ERROR, "unrecognized strategy: %d", strategy);
483  }
484 
485  /* If any check is failed, we have found our answer. */
486  if (!flag)
487  break;
488  }
489 
490  if (flag)
491  {
492  traversalValues[out->nNodes] = next_cube_box;
493  nodeNumbers[out->nNodes] = i;
494  out->nNodes++;
495  }
496  else
497  {
498  /*
499  * If this node is not selected, we don't need to keep the next
500  * traversal value in the memory context.
501  */
502  pfree(next_cube_box);
503  }
504  }
505 
506  /* Pass to the next level only the values that need to be traversed */
507  out->nodeNumbers = (int *)palloc(sizeof(int) * out->nNodes);
508  out->traversalValues = (void **)palloc(sizeof(void *) * out->nNodes);
509  for (i = 0; i < out->nNodes; i++)
510  {
511  out->nodeNumbers[i] = nodeNumbers[i];
512  out->traversalValues[i] = traversalValues[i];
513  }
514  pfree(nodeNumbers);
515  pfree(traversalValues);
516 
517  /* Switch after */
518  MemoryContextSwitchTo(old_ctx);
519 
520  PG_RETURN_VOID();
521 }
#define SPGOverlapStrategyNumber
#define SPGSameStrategyNumber
#define SPGContainedByStrategyNumber
#define SPGContainsStrategyNumber
static bool overlapND(CubeGIDX *cube_box, GIDX *query)
static CubeGIDX * nextCubeBox(CubeGIDX *cube_box, GIDX *centroid, uint16_t octant)
static CubeGIDX * initCubeBox(int ndims)
static bool containND(CubeGIDX *cube_box, GIDX *query)
#define LW_FAILURE
Definition: liblwgeom.h:110
Datum centroid(PG_FUNCTION_ARGS)

References centroid(), containND(), initCubeBox(), LW_FAILURE, nextCubeBox(), overlapND(), SPGContainedByStrategyNumber, SPGContainsStrategyNumber, SPGOverlapStrategyNumber, and SPGSameStrategyNumber.

Here is the call graph for this function: