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