int
saf_find_alternate_indexspecs(SAF_ParMode pmode, /* The parallel mode */
SAF_Set *containing_set, /* The containing set of the collection.*/
SAF_Cat *cat, /* The collection category. */
const char *name_grep, /* The name of the alt index spec you wish to search for. Pass NULL if
* you do not wish to limit the search via a name. */
int *num, /* For this and the succeeding argument [see Returned Handles]. */
SAF_AltIndexSpec **found /* For this and the preceding argument [see Returned Handles]. */
)
{
SAF_ENTER(saf_find_alternate_indexspecs, SAF_PRECONDITION_ERROR);
SAF_KEYMASK(SAF_AltIndexSpec, key, mask);
ss_collection_t coll=SS_COLLECTION_NULL;
ss_indexspec_t *ispec=NULL;
size_t nispecs=0, i;
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(_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"));
if (!_saf_is_self_decomp(cat)) {
/* Get the array of index specifications for the collection. Skip the first one, which is the default index spec. */
if (NULL==_saf_getCollection_set(containing_set, cat, &coll))
SAF_ERROR(SAF_FILE_ERROR, _saf_errmsg("unable to get collection"));
nispecs = ss_array_nelmts(SS_COLLECTION_P(&coll,indexing));
nispecs -= 1;
ispec = ss_array_get(SS_COLLECTION_P(&coll,indexing), ss_pers_tm, (size_t)1, nispecs, NULL);
/* If a name is supplied then prune the return value according to that name (or regular expression). Prune in such a
* way as to keep the index specs in their definition order. */
if (name_grep) {
if ('@'==*name_grep) {
SAF_SEARCH_RE(SAF_AltIndexSpec, key, mask, name, name_grep+1);
} else {
SAF_SEARCH_S(SAF_AltIndexSpec, key, mask, name, name_grep);
}
i=0;
while (i<nispecs) {
if (0==ss_pers_cmp((ss_pers_t*)ispec+i, (ss_pers_t*)key, (ss_persobj_t*)&mask)) {
i++;
} else {
--nispecs;
memmove(ispec+i, ispec+i+1, (nispecs-i)*sizeof(*ispec));
}
}
}
}
/* Return only what the caller asked for... */
if (!found) {
/* Count the matches */
assert(num);
*num = nispecs;
} else if (!*found) {
/* Find all matches; library allocates results */
*found = ispec;
ispec = NULL;
if (num) *num = nispecs;
} else {
/* Find limited matches; client allocates result buffer */
assert(num);
if (nispecs>(size_t)*num)
SAF_ERROR(SAF_CONSTRAINT_ERROR, _saf_errmsg("found too many matching objects"));
*found = ispec;
ispec = NULL;
*num = nispecs;
}
SS_FREE(ispec);
SAF_LEAVE(SAF_SUCCESS);
}