Compares two persistent objects¶
ss_pers_cmp
is a function defined in sspers.c.
Synopsis:
-
int
ss_pers_cmp
(ss_pers_t *p1, ss_pers_t *p2, const ss_persobj_t *mask)¶
Formal Arguments:
p1
: First of two objects to compare.p2
: Second of two objects to cmpare.mask
: Optional mask to use for deep comparisons. A null value implies a shallow comparison, which means that the comparison should only look at the object handles and not the objects themselves.
Description: Compares two objects, P1
and P2
, and returns a value similar to memcmp
or strcmp
.
If mask
is the null pointer then only the contents of the links P1
and P2
are consulted and the underlying
objects are never referenced, a so called shallow comparison. The return value will be one of the following:
1 2 3 4 | | 1 if A > B by some well defined global ordering
ss_pers_cmp(A,B,NULL) = | 0 if A and B point to the same object
| -1 if A < B
| -2 on error
|
On the other hand, if mask
is not null then a deep comparison is performed and mask
should be a block of
memory the same size as the objects to which P1
and P2
point (mask
is not referenced if P1
and P2
point to
objects of different types). The block of memory should be initialized to zero except where a comparison in
the two underlying objects is desired. For instance, when comparing the roles and topological dimensions of
two categories (SAF__Cat
) you would do the following:
1 2 3 4 5 6 | SAF_Cat a=...; b=...;
ss_catobj_t mask;
memset(&mask, 0, sizeof mask);
memset(&mask.role, SS_VAL_CMP_DFLT, 1); // default comparison mode for roles
memset(&mask.tdim, SS_VAL_CMP_DFLT, 1); // default comparison mode for topological dimensions
ss_pers_cmp((ss_pers_t*)&a, (ss_pers_t*)&b, (ss_persobj_t*)&mask);
|
Note two things: (1) only the first non-zero byte in the mask corresponding to any particular member is
consulted to determine the kind of comparison, and (2) ss_pers_t
and ss_persobj_t
are the types from which all
persistent object links and objects are derived and are binary compatible with all links and objects.
To compare all fields of two categories you could just set the whole mask to the desired comparison because
ss_pers_cmp
will skip over parts of the mask that don’t actually correspond to things that can be compared
(e.g., padding bytes inserted by the compiler between members of the object and parts of the objects that
are SSlib’s private bookkeeping records):
1 | memset(&mask, SS_VAL_CMP_DFLT, sizeof mask);
|
The various flags defining comparisons are defined by the ss_val_cmp_t type.
Return Value: Similar to memcmp
except successful return value is one of: -1, 0, or 1 instead of arbitrary negative and
positive values. This allows -2 (or less) to indicate failure, which is standard practice in SSlib for
comparison functions.
Parallel Notes: Independent
Issues: Deep comparisons are not yet fully recursive. I.e., if P1
and P2
are being deeply compared and the objects to
which P1
and P2
point contain object links which are being compared because they correspond to non-zero bits
in mask
, then only a shallow comparison is performed on those links. We plan to add a property list argument
to this function that would allow finer-grained control of the deep comparison recursion.
See Also:
- SS_PERS_EQ: 7.27: Determine link equality
- SS_PERS_EQUAL: 7.28: Determine object equality
- ss_pers_eq: 7.12: Determine link equality
- ss_pers_equal: 7.13: Determine object equality
- Persistent Objects: Introduction for current chapter