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
 size_t
 ss_table_indirect(ss_table_t *table,            /* Table in which IDX exists */
                   size_t idx,                   /* Index for the object for which we are searching for an indirect index. This
                                                  * is usually a direct index but doesn't necessarily have to be such. */
                   size_t beyond                 /* Return an indirect index greater than this value. A value of zero means to
                                                  * return the first indirect index. This argument can be used to scan through
                                                  * a table looking for all matching indirect indices for a particular direct
                                                  * index. If this is a direct index (such as zero) then the first matching
                                                  * indirect index is returned. */
                   )
 {
     SS_ENTER(ss_table_indirect, size_t);
     ss_persobj_t        *persobj=NULL;
     size_t              retval = SS_NOSIZE;
     size_t              first_subtab, subtabidx, nelmts, i;

     SS_ASSERT_TYPE(table, ss_table_t);
     SS_ASSERT(SS_TABLE_STATE_READ==table->state || SS_TABLE_STATE_CLOSED==table->state);
     if (SS_NOSIZE==beyond) SS_ERROR_FMT(USAGE, ("BEYOND is out of range"));

     /* Get the object address and minimum return value */
     if (NULL==(persobj=ss_table_lookup(table, idx, SS_STRICT))) SS_ERROR(FAILED);
     if (beyond & SS_TABLE_INDIRECT) {
         beyond++;
         first_subtab = ss_table_localidx(&beyond);
     } else {
         first_subtab = beyond = 0;
     }

     /* Scan through the indirect pointers to find the first one that points to persobj */
     for (subtabidx=first_subtab; subtabidx<SS_NSUBTABLES; subtabidx++) {
         if (NULL==table->maptab[subtabidx]) continue;
         nelmts = ss_table_subsize(subtabidx);
         for (i=beyond; i<nelmts; i++) {
             if (table->maptab[subtabidx][i]==persobj) {
                 retval = SS_TABLE_INDIRECT | ss_table_globalidx(subtabidx, i);
                 goto done;
             }
         }
         beyond = 0; /*start at zero in the next subtable*/
     }

 done:
 SS_CLEANUP:
     SS_LEAVE(retval);
 }