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
 int
 saf_find_matching_sets(SAF_ParMode pmode,       /* The parallel mode. */
                        SAF_Db *db,              /* The database in which to search */
                        const char *name_grep,   /* The name of the desired set(s) or a limited regular expression that the
                                                  * set names must match. If this argument begins with a leading "at sign", '@',
                                                  * character, the remaining characters will be treated as a limited form of
                                                  * a regular expression akin to that supported by 'ed.' The constant SAF_ANY_NAME
                                                  * can be passed if the client does not want to limit the search by name. */
                        SAF_SilRole srole,       /* The subset inclusion lattice role of the desired set(s). The SAF_ANY_SILROLE
                                                  * constant can be passed if the client is not interested in restricting the
                                                  * search on this criteria. */
                        int tdim,                /* The topological dimension of the desired set(s). The SAF_ANY_TOPODIM constant
                                                  * can be passed if the client is not interested in restricting the search on this
                                                  * criteria. */
                        SAF_ExtendMode extmode,  /* User to specify if the set is extendible or not (whether it can grow or not).
                                                  * Pass SAF_EXTENDIBLE_TRUE, SAF_EXTENDIBLE_FALSE, or SAF_EXTENDIBLE_TORF */
                        SAF_TopMode topmode,     /* whether the matching sets should be top sets. Pass SAF_TOP_TRUE, SAF_TOP_FALSE,
                                                  * or SAF_TOP_TORF */
                        int *num,                /* For this and the succeeding argument [see Returned Handles]. */
                        SAF_Set **found          /* For this and the preceding argument [see Returned Handles]. */
                        )
 {
     SAF_ENTER(saf_find_matching_sets, SAF_PRECONDITION_ERROR);
     SAF_KEYMASK(SAF_Set, 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_FILE(db), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("DATABASE must be a database handle"));
     SAF_REQUIRE(srole == SAF_SUITE || srole == SAF_TIME || srole == SAF_SPACE || srole == SAF_PARAM || srole == SAF_ANY_SILROLE,
                 SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("the SROLE must be one of SAF_TIME, SAF_SPACE, SAF_PARAM, or SAF_ANY_SILROLE"));
     SAF_REQUIRE(srole != SAF_TIME || tdim == 1, SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("if SROLE is TIME then TDIM must be 1"));
     SAF_REQUIRE(tdim >= 0 || tdim == SAF_ANY_TOPODIM, SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("TDIM must be SAF_ANY_TOPODIM or positive"));
     SAF_REQUIRE(extmode == SAF_EXTENDIBLE_TRUE || extmode == SAF_EXTENDIBLE_FALSE || extmode == SAF_EXTENDIBLE_TORF,
                 SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("EXTMODE cannot be arbitrarily non-zero for truth"));
     SAF_REQUIRE(topmode == SAF_TOP_TRUE || topmode == SAF_TOP_FALSE || topmode == SAF_TOP_TORF,
                 SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
                 _saf_errmsg("TOPMODE cannot be arbitrarily non-zero for truth"));
     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 record with stuff to look for */
     ss_file_topscope(db, &scope);
     if (name_grep) {
         if (name_grep[0] == '@') {
             SAF_SEARCH_RE(SAF_Set, key, mask, name, name_grep+1);
         } else {
             SAF_SEARCH_S(SAF_Set, key, mask, name, name_grep);
         }
     }
     if (srole != SAF_ANY_SILROLE)
         SAF_SEARCH(SAF_Set, key, mask, srole, srole);
     if (tdim != SAF_ANY_TOPODIM)
         SAF_SEARCH(SAF_Set, key, mask, tdim, tdim);
     if (topmode != SAF_TOP_TORF)
         SAF_SEARCH(SAF_Set, key, mask, is_top, topmode);
     if (extmode != SAF_EXTENDIBLE_TORF)
         SAF_SEARCH(SAF_Set, key, mask, is_extendible, extmode);

     /*  Now, find ids of matching records... */
     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_set_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);
 }