int
saf_find_topo_relations(SAF_ParMode pmode, /* The parallel mode. */
SAF_Db *db, /* The database in which to search for topology relations. */
SAF_Set *set, /* The set whose topology is sought. */
SAF_Set *topo_ancestor, /* [OUT] In many cases, the topology for a given set is known only on some
* ancestor of the set. This return value indicates that ancestor. If
* SAF_EQUIV() for SET and TOPO_ANCESTOR is true, then the topology
* relations found by this call are indeed those defined on the
* specified set. Otherwise, they are defined on the TOPO_ANCESTOR. */
int *num, /* For this and the succeeding argument, (see Returned Handles). */
SAF_Rel **found /* For this and the preceding argument, (see Returned Handles). */
)
{
SAF_ENTER(saf_find_topo_relations, SAF_PRECONDITION_ERROR);
SAF_KEYMASK(SAF_Rel, key, mask);
size_t nfound;
ss_scope_t scope;
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(-1);
SAF_REQUIRE(SS_SET(set), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("SET must be a valid handle"));
#if 0 /*not currently used*/
SAF_REQUIRE(topo_ancestor, SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("TOPO_ANCESTOR must be non-null"));
#else
if (topo_ancestor) *topo_ancestor = SS_SET_NULL;
#endif
SAF_REQUIRE(_saf_valid_memhints(num, (void**)found), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("NUM and FOUND must be compatible for return value allocation"));
/* fill in search criteria */
ss_file_topscope(db, &scope);
SAF_SEARCH(SAF_Rel, key, mask, sub, *set);
SAF_SEARCH(SAF_Rel, key, mask, kind, SAF_RELKIND_SUBSET);
if (!found) {
/* Count the matches */
assert(num);
nfound = SS_NOSIZE;
ss_pers_find(&scope, (ss_pers_t*)key, mask_count?(ss_persobj_t*)&mask:NULL, 0, &nfound, SS_PERS_TEST, NULL);
*num = nfound;
} else if (!*found) {
/* Find all matches; library allocates results */
nfound = SS_NOSIZE;
*found = (ss_rel_t*)ss_pers_find(&scope, (ss_pers_t*)key, mask_count?(ss_persobj_t*)&mask:NULL, 0, &nfound, NULL, NULL);
if (num) *num = nfound;
} else {
/* Find limited matches; client allocates result buffer */
assert(num);
nfound = *num;
if (NULL==ss_pers_find(&scope, (ss_pers_t*)key, mask_count?(ss_persobj_t*)&mask:NULL, 0, &nfound, (ss_pers_t*)*found,
_SAF_GLOBALS.find_detect_overflow)) {
SAF_ERROR(SAF_CONSTRAINT_ERROR, _saf_errmsg("found too many matching objects"));
}
*num = nfound;
}
SAF_LEAVE(SAF_SUCCESS);
}