PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches

◆ 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}
static CubeBox3D * initCubeBox(void)
#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 bool containND(CubeGIDX *cube_box, GIDX *query)
#define LW_FAILURE
Definition liblwgeom.h:96
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: