catalog.h#

#include <sif/structures/catalog.h>
SIF_STRUCTURES_CATALOG_H#

Growable list of voids: centre and radius, one entry each.

This is what a finder produces and what the measurement code consumes. It grows by appending, since a finder does not know how many voids it will find until it has finished looking.

struct sif_catalog_t#

A void catalogue.

Note

cx/cy/cz/radii are views into a single cache-line aligned arena (#_block). They move whenever the capacity changes, so never cache them across an append or a trim.

sif_real *_block#

Backing arena holding all four views. Owned; not for callers.

sif_real *cx#

Void centres, x axis.

sif_real *cy#

Void centres, y axis.

sif_real *cz#

Void centres, z axis.

sif_real *radii#

Void radii.

sif_real *_footprint_block#
Backing arena for the two footprint views, or NULL when the catalogue
  • carries none. Owned; not for callers.

sif_real *footprint#

Fraction of each void’s sphere that lies inside the survey footprint, in [0, 1], or NULL for a catalogue that has no footprint – a periodic box, where every void is whole by construction.

Written by sif_finder_exodus_survey(). A void added afterwards with sif_catalog_append() reads #SIF_CATALOG_FOOTPRINT_UNKNOWN here until something measures it.

sif_real *footprint_shell#

The same fraction over the shell between one and two radii, which is what says whether the void’s surroundings were observed – the part a stacked profile reaches into. NULL exactly when #footprint is.

uint64_t n_voids#

Entries in use.

uint64_t capacity#

Entries the arena can hold before it must grow.

SIF_CATALOG_FOOTPRINT_UNKNOWN#

What a footprint column holds for a void nobody has measured it for. Negative, so it cannot be mistaken for a fraction.

sif_catalog_t *sif_catalog_alloc(uint64_t initial_capacity)#

Allocate an empty catalogue.

Parameters:
  • initial_capacity – Entries to make room for up front. Clamped up to 1, so a successfully returned catalogue is always usable. Sizing it near the expected void count avoids the copies that growth costs.

Returns:

The catalogue, owned by the caller and released with sif_catalog_free(). NULL on allocation failure.

void sif_catalog_free(sif_catalog_t *catalog)#

Release a catalogue and its arena.

Parameters:
  • catalog – Catalogue to free. NULL is accepted and ignored.

int sif_catalog_append(sif_catalog_t *catalog, sif_real x, sif_real y, sif_real z, sif_real r)#

Append one void, doubling the capacity if it is full.

Doubling rather than growing by a fixed step keeps the total copying linear in the number of appends, which matters because a finder appends one void at a time and may find millions.

Parameters:
  • catalog – Catalogue to append to.

  • x – Void centre, x axis.

  • y – Void centre, y axis.

  • z – Void centre, z axis.

  • r – Void radius.

Returns:

SIF_OK on success. SIF_ERR_ALLOC if the catalogue could not grow, in which case it is left untouched and the void is NOT stored. SIF_ERR_INVALID on a NULL catalogue.

Warning

Invalidates cx/cy/cz/radii whenever it grows.

int sif_catalog_trim(sif_catalog_t *catalog)#

Release the capacity a catalogue is not using.

Worth calling once a finder has finished, since doubling leaves up to half the arena unused and a catalogue is usually kept for the rest of the run.

Parameters:
  • catalog – Catalogue to trim.

Returns:

SIF_OK on success, including when there is nothing to trim. SIF_ERR_ALLOC if the smaller buffer could not be allocated, in which case the catalogue keeps its current larger allocation and stays fully valid. SIF_ERR_INVALID on a NULL catalogue.

Warning

Invalidates cx/cy/cz/radii.

int sif_catalog_translate(sif_catalog_t *catalog, const sif_real offset[3])#

Shift every void centre by offset.

The way back out of the box a survey was searched in: pass the negated offset that sif_field_translate() moved the survey in by, and the centres return to the caller’s own frame. Radii and footprints are unchanged.

Parameters:
  • catalog – The catalogue, modified in place.

  • offset – Added to cx, cy and cz respectively.

Returns:

SIF_OK, or SIF_ERR_INVALID on a NULL argument.

int sif_catalog_reserve_footprint(sif_catalog_t *catalog)#

Give the catalogue its footprint columns, sif_catalog_t::footprint and sif_catalog_t::footprint_shell.

Optional because most catalogues have no use for them: a void found in a periodic box is whole by construction. Once reserved they follow the catalogue through every append and trim. A no-op if they already exist.

Parameters:
  • catalog – The catalogue.

Returns:

SIF_OK, SIF_ERR_INVALID on a NULL catalogue, or SIF_ERR_ALLOC, in which case the catalogue is left without them.

Note

Every void already in the catalogue starts at #SIF_CATALOG_FOOTPRINT_UNKNOWN.