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
 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);
 }