int
ss_pers_cmp(ss_pers_t *p1, /* First of two objects to compare. */
ss_pers_t *p2, /* Second of two objects to cmpare. */
const ss_persobj_t *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. */
)
{
SS_ENTER(ss_pers_cmp, int);
int retval=0;
SS_RETVAL(-2); /* Comparison functions return -2 for failure since -1 means P1<P2 */
/* Check basic stuff that we need to do for both shallow and deep comparisons. */
if (SS_PERS_ISNULL(p1) && SS_PERS_ISNULL(p2)) {
goto done;
} else if (SS_PERS_LINK_NULL==ss_pers_link_state(p1)) {
retval = -1;
goto done;
} else if (SS_PERS_LINK_NULL==ss_pers_link_state(p2)) {
retval = 1;
goto done;
}
/* Some error checks */
if (SS_PERS_LINK_RESERVED==ss_pers_link_state(p1) || SS_PERS_LINK_RESERVED==ss_pers_link_state(p2))
SS_ERROR_FMT(USAGE, ("P1 and/or P2 have reserved state"));
SS_ASSERT_CLASS(p1, ss_pers_t);
SS_ASSERT_CLASS(p2, ss_pers_t);
/* More stuff for both shallow and deep */
if (SS_MAGIC_SEQUENCE(SS_MAGIC_OF(p1)) < SS_MAGIC_SEQUENCE(SS_MAGIC_OF(p2))) {
retval = -1;
goto done;
} else if (SS_MAGIC_SEQUENCE(SS_MAGIC_OF(p1)) > SS_MAGIC_SEQUENCE(SS_MAGIC_OF(p2))) {
retval = 1;
goto done;
}
/* This stuff is only applicable to a shallow comparison. Object handles are unequal if:
* 1. They point to different files, or
* 2. They point to different scopes, or
* 3. They point to different table entries */
if (!mask) {
if (ss_pers_link_gfileidx(p1) < ss_pers_link_gfileidx(p2)) {
retval = -1;
goto done;
} else if (ss_pers_link_gfileidx(p1) > ss_pers_link_gfileidx(p2)) {
retval = 1;
goto done;
} else if (ss_pers_link_scopeidx(p1) < ss_pers_link_scopeidx(p2)) {
retval = -1;
goto done;
} else if (ss_pers_link_scopeidx(p1) > ss_pers_link_scopeidx(p2)) {
retval = 1;
goto done;
}
if (ss_pers_update(p1)<0) SS_ERROR(FAILED);
if (ss_pers_update(p2)<0) SS_ERROR(FAILED);
if (ss_pers_link_objidx(p1) < ss_pers_link_objidx(p2)) {
retval = -1;
goto done;
} else if (ss_pers_link_objidx(p1) > ss_pers_link_objidx(p2)) {
retval = 1;
goto done;
}
}
/* This stuff is only applicable to a deep comparison. */
if (mask) {
ss_persobj_t *po1, *po2;
if (NULL==(po1=ss_pers_deref(p1))) SS_ERROR(FAILED);
if (NULL==(po2=ss_pers_deref(p2))) SS_ERROR(FAILED);
if (-2==(retval=ss_pers_cmp_(po1, po2, mask))) SS_ERROR(FAILED);
}
done:
SS_CLEANUP:
SS_LEAVE(retval);
}