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 | int
saf_find_collections(SAF_ParMode pmode, /* The parallel mode. */
SAF_Set *containing_set, /* The containing set in which to search for collections. In SAF_ONE()
* parallel mode, all processes except the process identified by the
* rank argument of the SAF_ONE() macro are free to pass SAF_NULL_SET
* with the set's database handle. */
SAF_Role *role, /* The role of the collection. Pass NULL if you do not wish to
* limit the search by this parameter. */
SAF_CellType cell_type, /* The cell-type of the members of the collection. Pass SAF_ANY_CELLTYPE if you
* do not wish to limit the search by this parameter. */
int topo_dim, /* The topological dimension of the collection. Pass SAF_ANY_TOPODIM if you do not
* wish to limit the search by this parameter. */
SAF_DecompMode decomp_mode,/* Whether the found collections must be a decomposition of the containing set.
* Pass SAF_DECOMP_TORF if it does not matter. */
int *num, /* For this and the succeeding argument, (see Returned Handles). */
SAF_Cat **found /* For this and the preceding argument, (see Returned Handles). */
)
{
SAF_ENTER(saf_find_collections, SAF_PRECONDITION_ERROR);
SAF_KEYMASK(SAF_Cat, cat_key, cat_mask);
SAF_KEYMASK(SAF_Collection, coll_key, coll_mask);
ss_catobj_t *cat_mask_p=NULL, cat_mask_z;
ss_collectionobj_t *coll_mask_p=NULL, coll_mask_z;
size_t ncolls; /* Number of collections in CONTAINING_SET */
size_t nfound=0; /* Number of matches found */
size_t limit=SS_NOSIZE; /* Limit number of matches returned */
size_t i;
ss_collection_t coll;
ss_cat_t cat;
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(containing_set), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("CONTAINING_SET must be a valid set handle for participating processes"));
SAF_REQUIRE(_saf_valid_memhints(num, (void**)found), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("NUM_COLLS and CATS must be compatible for return value allocation"));
SAF_REQUIRE(!role || SS_ROLE(role), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("ROLE must be a valid role handle if supplied"));
/* Fill in the collection and category keys with desired information */
if (cell_type != SAF_CELLTYPE_ANY)
SAF_SEARCH(SAF_Collection, coll_key, coll_mask, cell_type, cell_type);
if (topo_dim != SAF_ANY_TOPODIM)
SAF_SEARCH(SAF_Cat, cat_key, cat_mask, tdim, topo_dim);
if (decomp_mode != SAF_DECOMP_TORF)
SAF_SEARCH(SAF_Collection, coll_key, coll_mask, is_decomp, decomp_mode?TRUE:FALSE);
/* Allocate return value. */
ncolls = ss_array_nelmts(SS_SET_P(containing_set,colls));
if (!found) {
/* Only counting */
assert(num);
*num=0;
} else if (!*found) {
/* Library allocates results */
*found = calloc(ncolls, sizeof **found);
if (num) *num = 0;
} else {
/* Client allocated results */
assert(num);
assert(*num>=0);
limit = *num;
*num = 0;
}
/* If the collection or catetory masks are empty then we should pass null for the mask arguments in order to match
* everything and avoid an error regarding an empty mask. */
memset(&coll_mask_z, 0, sizeof coll_mask_z);
memset(&cat_mask_z, 0, sizeof cat_mask_z);
coll_mask_p = memcmp(&coll_mask, &coll_mask_z, sizeof coll_mask) ? &coll_mask : NULL;
cat_mask_p = memcmp(&cat_mask, &cat_mask_z, sizeof cat_mask) ? &cat_mask : NULL;
/* Scan through the collections associated with the containing_set */
for (i=0; i<ncolls; i++) {
ss_array_get(SS_SET_P(containing_set,colls), 0, i, 1, &coll);
cat = SS_COLLECTION(&coll)->cat;
/* If a role is specified then determine whether it is the same role as what is associated with the cat for this
* collection for this set. Since collections of the self category can be explicitly stored in the set's collection
* list then we have to be prepared for the case when cat->role is a null object link (because the "self" collection
* category isn't allowed to point to a particular role. */
if (role) {
if (SS_PERS_ISNULL(SS_CAT_P(&cat,role))) continue;
if (!SS_PERS_EQUAL(role, SS_CAT_P(&cat,role))) continue;
}
/* Compare the collection and category with the keys we initialized above. */
if (coll_mask_p && 0!=ss_pers_cmp((ss_pers_t*)&coll, (ss_pers_t*)coll_key, (ss_persobj_t*)coll_mask_p)) continue;
if (cat_mask_p && 0!=ss_pers_cmp((ss_pers_t*)&cat, (ss_pers_t*)cat_key, (ss_persobj_t*)cat_mask_p)) continue;
/* Found a match. */
if (nfound>=limit)
SAF_ERROR(SAF_CONSTRAINT_ERROR, _saf_errmsg("found too many matching objects"));
if (found)
(*found)[nfound] = cat;
nfound++;
}
if (num) *num = nfound;
SAF_LEAVE(SAF_SUCCESS);
}
|