Find objects in a scope¶
ss_pers_find
is a function defined in sspers.c.
Synopsis:
-
ss_pers_t *
ss_pers_find
(ss_scope_t *scope, ss_pers_t *key, ss_persobj_t *mask, size_t nskip, size_t *nfound, ss_pers_t *buffer, ss_prop_t *props)¶
Formal Arguments:
scope
: Scope to be searchedkey
: Value for which to search. This is required even ifmask
is null because thekey
determines the type of objects for which to search.mask
: Which elements ofkey
to consider when searching. It is an error if no bits ofmask
are set, but ifmask
is the null pointer thenkey
is assumed to match every object. If non-null thenmask
andkey
must be of the same type. The reasonmask
is an object pointer rather than an object link is that the memory is really only used to store one-byte flags that control how the matching is performed. In other words,mask
isn’t truly an object–it just has to be the same size as an object.nskip
: Number of initial matched results that should be skipped.nfound [INOUT]
: The input value limits the matching to the specified number ofbuffer
: Optional buffer to fill in with handles to items that were found. If this is the constantSS_PERS_TEST
then this function behaves exactly as if the caller had supplied a buffer but does not attempt to return links to the matching objects.props
: Optional properties (See *Persistent Object Properties*)
Description: This function will find all objects in a particular scope
that match certain fields of a specified key
object.
The key
and mask
must refer to persistent objects of the same type where key
contains the values to compare
against and mask
specifies which part of key
to consider and how to compare. However, the mask
is not a true
object in that it doesn’t need to be created in some table with ss_pers_new; it can just be allocated on the
stack. Any atomic element of mask
that has at least one bit set indicates that the corresponding element of
key
is to be considered during the comparison. If no bits of mask
are set then an error is raised, but if
mask
is the null pointer then we treat the key
as matching every object in the scope.
If nfound
is non-null then its incoming value will be used to limit the search to the specified number of
returned matches. If more items match than what was specified then the additional items are simply ignored as
if they didn’t even exist (unless the “detect_overflow
” property is true, in which case an error is raised).
The caller can pass in SS_NOSIZE
if no limit is desired. If nfound
is the null pointer (it can only be so if
buffer
is also null) then it is treated as if it had pointed to SS_NOSIZE
.
The caller can supply a buffer
for the result or, by passing a null pointer, request that the library allocate
the buffer. If buffer
is supplied then it must contain at least nfound
(as set on entry to this function)
elements to hold the result. But if buffer
is the special constant SS_PERS_TEST
then the function behaves as
if a valid buffer
was supplied except that it does not attempt to initialize that buffer in any way. This can
be used to count how many matches would be found and even limit the counting by supplying an initial value for
nfound
.
A positive value for an nskip
argument causes this function to act as if the first nskip
matched objects
didn’t, in fact, match.
Return Value: On success this function returns an array of matching persistent object links into the specified scope
(the
caller supplied buffer
or one allocated by the library) or the constant SS_PERS_TEST
and nfound
(if supplied)
will point to the number of matches found limited by the incoming value of nfound
(or SS_NOSIZE
). If space
permits, the last element of the return value will be followed by a null persistent link, which makes it
possible to loop over the return value even if nfound
was the null pointer.
In order to distinguish the case where no item is found from the case where an error occurs, the former
results in a non-null return value (the library will allocate an array of size one if the caller didn’t supply
a buffer
and initialize it to SS_PERS_NULL
). The nfound
returned value is zero in either case.
If no objects match in the specified scope and the object type is not ss_scope_t
or ss_file_t
and the
noregistries’ property is false or not set then each registry scope associated with the file containing ``scope`
will be searched until matches are found in some scope or all registries are processed.
This function returns the null pointer for failure. It is not considered a failure when the key
simply doesn’t
match any of the available objects.
Parallel Notes: Independent
Example: Example 1: Find all fields with an association ratio of 1 in the main scope:
1 2 3 4 5 6 7 8 9 10 11 12 13 | // Obtain key from a transient scope; allocate the mask on the stack
ss_field_t *key = SS_PERS_NEW(transient, ss_field_t, SS_ALLSAME);
ss_fieldobj_t mask;
// Set key value for which to search and indicate such in the mask
SS_FIELD(key)->assoc_ratio = 1;
memset(&mask, 0, sizeof mask);
mask.assoc_ratio = SS_VAL_CMP_DFLT; //default comparison
// Search for matches
size_t nfound = SS_NOSIZE;
ss_field_t *found = ss_pers_find(main, key, mask, 0, &nfound, NULL, NULL);
// Print names of all matches
for (i=0; i<nfound; i++)
printf("match %d name=\"%s\"\n",i,ss_string_ptr(SS_FIELD_P(found+i,name)));
|
Example 2: Find first 10 fields with a name consisting of the word “field” in any combination of upper and lower case letters, followed by one or more digits:
1 2 3 4 5 6 7 8 9 10 11 | // Obtain key from a transient scope; allocate the mask on the stack
ss_field_t *key = SS_PERS_NEW(transient, ss_field_t, SS_ALLSAME);
ss_fieldobj_t mask;
// Set key value for which to search and indicate such in the mask
ss_string_set(SS_FIELD_P(key,name), "^field[0-9]+$");
memset(&mask, 0, sizeof mask);
memset(&(mask.name), SS_VAL_CMP_RE_ICASE, 1);
// Search for matches
size_t nfound = 10;
ss_field_t found[10];
ss_pers_find(main, key, &mask, 0, &nfound, found, NULL);
|
Example 3: Count how many fields are in the scope proc1:
1 2 3 4 | ss_field_t *key = ....; // any field object
size_t nfound = SS_NOSIZE; // do not limit the search
ss_pers_find(proc1, key, NULL, 0, &nfound, SS_PERS_TEST, NULL);
printf("found %lu item(s)\n", (unsigned long)nfound);
|
See Also:
- ss_pers_new: 7.1: Create a new persistent object
- Persistent Objects: Introduction for current chapter