1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112 | int
saf_find_fields(SAF_ParMode pmode, /* The parallel mode. */
SAF_Db *db, /* Database in which to limit the search. */
SAF_Set *base, /* The base space to limit the search to. Pass SAF_UNIVERSE() or NULL if you
* do not want to limit the search to any particular base space. */
const char *name, /* Limit search to fields with this name. Pass SAF_ANY_NAME if you do not want
* to limit the search. */
SAF_Quantity *quantity, /* Limit search to fields of specified quantity. Pass NULL to not limit search. */
SAF_Algebraic *atype, /* Limit the search to this algebraic type. Pass SAF_ALGTYPE_ANY if you do
* not want to limit the search. */
SAF_Basis *basis, /* Limit the search to this basis. Pass SAF_ANY_BASIS if you do not want to
* limit the search. */
SAF_Unit *unit, /* Limit search to fields with these units. Pass SAF_ANY_UNIT to not limit
* search. */
SAF_Cat *coeff_assoc, /* Limit search. Pass SAF_ANY_CAT to not limit the search. */
int assoc_ratio, /* Limit search. Pass SAF_ANY_RATIO to not limit the search. */
SAF_Cat *eval_decomp, /* Limit search. Pass SAF_ANY_CAT to not limit the search. */
SAF_Eval *eval_func, /* Limit search. Pass SAF_ANY_EFUNC to not limit the search. */
int *nfound, /* For this and the succeeding argument, (see Returned Handles). */
SAF_Field **found /* For this and the preceding argument, (see Returned Handles). */
)
{
SAF_ENTER(saf_find_fields, SAF_PRECONDITION_ERROR);
SAF_KEYMASK(SAF_Field, key, mask);
int nftmpls=0, n;
SAF_FieldTmpl *ftmpls=NULL;
size_t thisListN, nret=0, i;
SAF_Field *thisList=NULL, *retval=found?*found:NULL;
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(!base || SS_SET(base), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("BASE must either be a valid set handle or the universe set if supplied"));
SAF_REQUIRE(!quantity || SS_QUANTITY(quantity), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("QUANTITY must either be a valid quantity handle or SAF_ANY_QUANTITY"));
SAF_REQUIRE(!atype || SS_ALGEBRAIC(atype), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("ATYPE must be a valid algebraic type handle or SAF_ANY_ALGEBRAIC"));
SAF_REQUIRE(!basis || SS_BASIS(basis), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("BASIS must be a valid basis handle or SAF_ANY_BASIS"));
SAF_REQUIRE(!unit || SS_UNIT(unit), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("UNIT must either be a valid unit handle or SAF_ANY_UNIT"));
SAF_REQUIRE(!eval_func || SS_EVALUATION(eval_func), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("EVAL_FUNC must be a valid evaluation function handle or SAF_ANY_EVALUATION"));
SAF_REQUIRE(!coeff_assoc || SS_CAT(coeff_assoc), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("COEFF_ASSOC must either be a valid cat handle or SAF_ANY_CAT"));
SAF_REQUIRE(!eval_decomp || SS_CAT(eval_decomp), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("EVAL_DECOMP must either be a valid cat handle or SAF_ANY_CAT"));
SAF_REQUIRE(_saf_valid_memhints(nfound, (void**)found), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("NFOUND and FOUND must be compatible for return value allocation"));
/* Where do we search? */
ss_file_topscope(db, &scope);
/* First find all the templates that match the search criteria, then loop over those templates to find the matching
* fields. */
if (atype || basis || quantity) {
saf_find_field_tmpls(pmode, db, NULL, atype, basis, quantity, &nftmpls, &ftmpls);
/* We're done early if the search criteria yielded no matching field template. */
if (0==nftmpls) {
if (found) *nfound = 0;
SAF_RETURN(SAF_SUCCESS);
}
}
/* Initialize the key/mask for the field search */
if (name) SAF_SEARCH_S(SAF_Field, key, mask, name, name);
if (coeff_assoc) SAF_SEARCH(SAF_Field, key, mask, dof_assoc_cat, *coeff_assoc);
if (SAF_ANY_INT!=assoc_ratio) SAF_SEARCH(SAF_Field, key, mask, assoc_ratio, assoc_ratio);
if (eval_decomp) SAF_SEARCH(SAF_Field, key, mask, eval_decomp_cat, *eval_decomp);
if (base && !_saf_is_universe(base)) SAF_SEARCH(SAF_Field, key, mask, base_space, *base);
if (unit) SAF_SEARCH(SAF_Field, key, mask, units, *unit);
if (eval_func) SAF_SEARCH(SAF_Field, key, mask, evaluation, *eval_func);
/* Now, loop over the number of field templates doing finds on the fields */
for (n=0; n<MAX(1, nftmpls); n++) {
/* Fill in the field template id for this pass if we have any */
if (ftmpls) SAF_SEARCH(SAF_Field, key, mask, ftmpl, ftmpls[n]);
/* Find fields matching key/mask */
thisList = SS_PERS_FIND(&scope, key, mask_count?&mask:NULL, SS_NOSIZE, thisListN);
/* Append these fields to the return value */
if (!found) {
/* Count the matches */
assert(nfound);
nret += thisListN;
} else if (!*found) {
/* Find all matches; library allocates results */
if (NULL==(retval=realloc(retval, MAX(nret+thisListN,1)*sizeof(*retval))))
SAF_ERROR(SAF_MEMORY_ERROR, _saf_errmsg("unable to allocate space for fields"));
for (i=0; i<thisListN; i++)
retval[nret++] = thisList[i];
} else {
/* Find limited matches; client allocates result buffer */
assert(nfound);
if ((int)(nret+thisListN)>*nfound)
SAF_ERROR(SAF_CONSTRAINT_ERROR, _saf_errmsg("found too many matching objects"));
for (i=0; i<thisListN; i++)
retval[nret++] = thisList[i];
}
thisList = SS_FREE(thisList);
}
/* Return values */
if (nfound) *nfound = nret;
if (found) *found = retval;
SAF_LEAVE(SAF_SUCCESS);
}
|