IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Dec 9, 2004, 4:50:16 PM (22 years ago)
Author:
desonia
Message:

Changed psList API for iterators, etc.

Location:
trunk/psLib/src/collections
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/psLib/src/collections/psCollectionsErrors.dat

    r2357 r2681  
    3232psHash_TABLE_NULL                      Input psHash can not be NULL.
    3333psHash_DATA_NULL                       Input data can not be NULL.
     34#
     35psList_LOCATION_INVALID                Specified location, %d, is invalid.
     36psList_ITERATOR_INVALID                Specified iterator is not valid.
     37psList_ITERATOR_NULL                   Specified iterator is NULL.
     38psList_LIST_NULL                       Specified psList reference is NULL.
     39psList_DATA_NULL                       Specified data item is NULL.
     40psList_DATA_NOT_FOUND                  Specified data item is not found in the psList.
    3441
  • trunk/psLib/src/collections/psCollectionsErrors.h

    r2357 r2681  
    77 *  @author Robert DeSonia, MHPCC
    88 *
    9  *  @version $Revision: 1.6 $ $Name: not supported by cvs2svn $
    10  *  @date $Date: 2004-11-13 00:52:49 $
     9 *  @version $Revision: 1.7 $ $Name: not supported by cvs2svn $
     10 *  @date $Date: 2004-12-10 02:50:14 $
    1111 *
    1212 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    5050#define PS_ERRORTEXT_psHash_TABLE_NULL "Input psHash can not be NULL."
    5151#define PS_ERRORTEXT_psHash_DATA_NULL "Input data can not be NULL."
     52#define PS_ERRORTEXT_psList_LOCATION_INVALID "Specified location, %d, is invalid."
     53#define PS_ERRORTEXT_psList_ITERATOR_INVALID "Specified iterator is not valid."
     54#define PS_ERRORTEXT_psList_ITERATOR_NULL "Specified iterator is NULL."
     55#define PS_ERRORTEXT_psList_LIST_NULL "Specified psList reference is NULL. "
     56#define PS_ERRORTEXT_psList_DATA_NULL "Specified data item is NULL."
     57#define PS_ERRORTEXT_psList_DATA_NOT_FOUND "Specified data item is not found in the psList."
    5258//~End
    5359
  • trunk/psLib/src/collections/psList.c

    r2375 r2681  
    66 *  @author Robert Daniel DeSonia, MHPCC
    77 *
    8  *  @version $Revision: 1.22 $ $Name: not supported by cvs2svn $
    9  *  @date $Date: 2004-11-16 20:00:20 $
     8 *  @version $Revision: 1.23 $ $Name: not supported by cvs2svn $
     9 *  @date $Date: 2004-12-10 02:50:14 $
    1010 *
    1111 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    2929
    3030// private functions.
    31 static psListElem* listGetIterator(psList* list);
    32 static psS32 listGetIteratorIndex(psList* list);
    33 static void listSetIterator(psList* list, psS32 where, psBool lockList);
    3431static void listFree(psList* list);
    35 
    36 psList* psListAlloc(psPtr data)
    37 {
    38     psList* list = psAlloc(sizeof(psList));
    39 
    40     p_psMemSetDeallocator(list, (psFreeFcn) listFree);
    41 
    42     list->size = 0;
    43     list->head = list->tail = NULL;
    44     list->p_iter = ITER_INIT_HEAD;
    45     list->p_iterIndex = PS_LIST_HEAD;
    46 
    47     pthread_mutex_init(&(list->lock), NULL)
    48     ;
    49 
    50     if (data != NULL) {
    51         psListAdd(list, PS_LIST_TAIL, data);
    52     }
    53 
    54     return list;
    55 }
     32static void listIteratorFree(psListIterator* iter);
     33static psBool listIteratorRemove(psListIterator* iterator);
    5634
    5735static void listFree(psList* list)
     
    6442    ;
    6543
     44    psFree(list->iterators);
     45
    6646    for (psListElem* ptr = list->head; ptr != NULL;) {
    6747        psListElem* next = ptr->next;
     
    8161}
    8262
    83 psBool psListAdd(psList* list, psS32 location, psPtr data)
    84 {
    85     psListElem* position;
    86     psListElem* elem;
    87     psS32 cursorIndex = 0;
    88 
    89     if (list == NULL) {
    90         return false;
    91     }
    92 
    93     if (data == NULL) {
    94         return false;
    95     }
    96 
    97     if (location <= PS_LIST_UNKNOWN) {
    98         // / XXX What is the better way to communicate this failure to the caller?
    99         psLogMsg(__func__, PS_LOG_WARN, "The given insert location (%i) for psListAdd is invalid.", location);
    100         return false;
    101     }
    102 
    103     elem = psAlloc(sizeof(psListElem));
     63static void listIteratorFree(psListIterator* iter)
     64{
     65    if (iter == NULL) {
     66        return;
     67    }
     68
     69    // remove this iterator from the parent list
     70    psArrayRemove(iter->list->iterators,iter);
     71
     72}
     73
     74static psBool listIteratorRemove(psListIterator* iterator)
     75{
     76    if (iterator == NULL) {
     77        return false;
     78    }
     79
     80    psListElem* elem = iterator->cursor;
     81    psList* list = iterator->list;
     82    int index = iterator->index;
    10483
    10584    pthread_mutex_lock(&list->lock)
    10685    ;
    10786
    108     if (location > 0 && location > list->size) {
    109         psLogMsg(__func__, PS_LOG_WARN,
    110                  "Invalid index %d (only %d elements in psList); assuming tail.", location, list->size);
    111         location = PS_LIST_TAIL;
    112     }
    113 
    114     if (location == PS_LIST_TAIL || list->size == 0) {
    115         // insert the element at the end of the list
    116         elem->prev = list->tail;
    117         elem->next = NULL;
    118 
    119         if (list->tail != NULL) {
    120             list->tail->next = elem;
    121         }
    122 
    123         if (list->head == NULL) {
    124             list->head = elem;
    125         }
    126         list->tail = elem;
    127 
    128         list->size++;
    129         list->p_iter = elem;
    130         list->p_iterIndex = list->size - 1;
    131     } else {
    132         // move ourselves to the given position
    133         listSetIterator(list, location, false);
    134         position = listGetIterator(list);
    135         cursorIndex = listGetIteratorIndex(list);
    136 
    137         if (position == NULL) {
    138             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    139                     "Failed to move cursor to specified location (%d)", location);
    140             position = list->head;         // since we no list->size != 0, this must be non-NULL
    141         }
    142         // insert our new element in front of the given position
    143         elem->prev = position->prev;
    144         elem->next = position;
    145         position->prev = elem;
    146 
    147         if (elem->prev == NULL) {          // must be front of list
    148             list->head = elem;
    149         } else {
    150             elem->prev->next = elem;
    151         }
    152 
    153         list->size++;
    154         list->p_iter = elem;
    155         list->p_iterIndex = cursorIndex;
    156     }
    157 
    158     elem->data = psMemIncrRefCounter(data);
    159 
    160     pthread_mutex_unlock(&list->lock)
    161     ;
    162 
    163     return true;
    164 }
    165 
    166 
    167 /*
    168  * Remove an element from a list
    169  */
    170 psBool psListRemove(psList* list, psS32 location, psPtr data)
    171 {
    172     psListElem* elem = NULL;    // element to remove
    173     psS32 cursorIndex = 0;
    174 
    175     if (list == NULL) {
    176         psError(PS_ERR_BAD_PARAMETER_NULL, true, "list parameter found to be NULL.");
    177         return false;
    178     }
    179     // get exclusive access to list so that other threads will not get in the way.
    180     pthread_mutex_lock(&list->lock)
    181     ;
    182 
    183     if (location == PS_LIST_UNKNOWN) {
    184         // search list for the data item.
    185 
    186         psS32 i = 0;              // index
    187 
    188         for (psListElem* ptr = list->head; ptr != NULL; ptr = ptr->next) {
    189             if (ptr->data == data) {
    190                 location = i;
    191                 break;
    192             }
    193             i++;
    194         }
    195 
    196         if (location == PS_LIST_UNKNOWN) {
    197             psError(PS_ERR_BAD_PARAMETER_VALUE, true, "Failed to find item in given psList.");
    198             pthread_mutex_unlock(&list->lock)
    199             ;
    200             return false;
    201         }
    202     }
    203     // position the list's cursor to the desired location
    204     listSetIterator(list, location, false);
    205     elem = listGetIterator(list);
    206     cursorIndex = listGetIteratorIndex(list);
    207 
    208     if (elem == NULL) {
    209         psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    210                 "Couldn't position to given index (%d) to remove element from list.", location);
    211         pthread_mutex_unlock(&list->lock)
    212         ;
    213         return false;
    214     }
    215 
    216     list->size--;
    217 
    218     if (elem->prev == NULL) {              // head of list?
     87    if (elem == list->head) {        // head of list?
    21988        list->head = elem->next;
    22089    } else {
     
    22291    }
    22392
    224     if (elem->next == NULL) {              // tail of list?
     93    if (elem == list->tail) {        // tail of list?
    22594        list->tail = elem->prev;
    226 
    227         // removed tail, so iter should be the last element of list to keep it valid
    228         if (list->size > 0) {
    229             list->p_iter = list->tail;
    230             list->p_iterIndex = list->size - 1;
     95    } else {
     96        elem->next->prev = elem->prev;
     97    }
     98
     99    psArray* iterators = list->iterators;
     100    for (int i = 0; i < iterators->n; i++) {
     101        psListIterator* iter = (psListIterator*) iterators->data[i];
     102        if (iter->cursor == elem) {
     103            iter->cursor = NULL;
     104        } else if (iter->index > index) {
     105            iter->index--;
     106        }
     107    }
     108
     109    list->size--;
     110
     111    pthread_mutex_unlock(&list->lock)
     112    ;
     113
     114    // OK, delete orphaned list element and its data
     115    psFree(elem->data);
     116    psFree(elem);
     117
     118    return true;
     119}
     120
     121psList* psListAlloc(psPtr data)
     122{
     123    psList* list = psAlloc(sizeof(psList));
     124
     125    p_psMemSetDeallocator(list, (psFreeFcn) listFree);
     126
     127    list->size = 0;
     128    list->head = list->tail = NULL;
     129    list->iterators = psArrayAlloc(16);
     130
     131    // create a default iterator
     132    list->iterators->data[0] = psListIteratorAlloc(list,PS_LIST_HEAD);
     133    list->iterators->n = 1;
     134
     135    pthread_mutex_init(&(list->lock), NULL)
     136    ;
     137
     138    if (data != NULL) {
     139        psListAdd(list, PS_LIST_TAIL, data);
     140    }
     141
     142    return list;
     143}
     144
     145psListIterator* psListIteratorAlloc(psList* list, int location)
     146{
     147    psListIterator* iter = psAlloc(sizeof(psListIterator));
     148
     149    p_psMemSetDeallocator(iter, (psFreeFcn) listIteratorFree);
     150
     151    // initialize the attributes
     152    iter->list = list;
     153    iter->cursor = NULL;
     154    iter->index = 0;
     155    iter->offEnd = false;
     156
     157    // add to the list's array of iterators
     158    psArray* listIterators = list->iterators;
     159    int num = listIterators->n;
     160    if ( num >= listIterators->nalloc) {
     161        // need to resize the array to make more room for another iterator.
     162        list->iterators = psArrayRealloc(listIterators,listIterators->nalloc*2);
     163        listIterators = list->iterators;
     164    }
     165    listIterators->data[num] = iter;
     166    listIterators->n = num+1;
     167
     168    if (! psListIteratorSet(iter,location)) {
     169        psFree(iter);
     170        iter = NULL;
     171    }
     172
     173    return iter;
     174}
     175
     176psBool psListIteratorSet(psListIterator* iterator,
     177                         int location)
     178{
     179    if (iterator == NULL) {
     180        return false;
     181    }
     182
     183    psList* list = iterator->list;
     184
     185    if (location >= list->size) {
     186        psLogMsg(__func__, PS_LOG_WARN,
     187                 "Specified index, %d, is beyond the end of the psList, which "
     188                 "has only %d elements.  Assuming tail.",
     189                 location, list->size);
     190        location = PS_LIST_TAIL;
     191    }
     192
     193    if (location == PS_LIST_TAIL) {
     194        iterator->cursor = list->tail;
     195        iterator->index = list->size - 1;
     196        iterator->offEnd = false;
     197        return true;
     198    }
     199
     200    if (location <= 0) {   // Invalid index
     201        return false;
     202    }
     203
     204
     205    psListElem* cursor = iterator->cursor;
     206    int index = iterator->index;
     207    if (cursor == NULL) {      // set the cursor to the head if it is NULL
     208        if (location > list->size/2) { // closer to tail or head?
     209            cursor = list->tail;
     210            index = list->size - 1;
    231211        } else {
    232             list->p_iter = ITER_INIT_TAIL;
     212            cursor = list->head;
     213            index = 0;
     214        }
     215    }
     216
     217    if (location < index) {
     218        psS32 diff = index - location;
     219
     220        for (psS32 count = 0; count < diff; count++) {
     221            cursor = cursor->prev; // shouldn't need to check for NULL
    233222        }
    234223    } else {
    235         elem->next->prev = elem->prev;
    236         list->p_iter = elem->next;
    237         list->p_iterIndex = cursorIndex;
     224        psS32 diff = location - index;
     225
     226        for (psS32 count = 0; count < diff; count++) {
     227            cursor = cursor->next; // shouldn't need to check for NULL
     228        }
     229    }
     230    iterator->cursor = cursor;
     231    iterator->index = location;
     232    iterator->offEnd = false;
     233
     234    return true;
     235}
     236
     237psBool psListAdd(psList* list, psS32 location, psPtr data)
     238{
     239
     240    if (list == NULL) {
     241        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     242                PS_ERRORTEXT_psList_LIST_NULL);
     243        return false;
     244    }
     245
     246    if (data == NULL) {
     247        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     248                PS_ERRORTEXT_psList_DATA_NULL);
     249        return false;
     250    }
     251
     252    // move ourselves to the given position
     253    if (list->iterators->n < 1 ||
     254            ! psListIteratorSet(list->iterators->data[0],location)) {
     255        // oh no, I can't find where to add this!
     256        psError(PS_ERR_UNKNOWN, false,
     257                PS_ERRORTEXT_psList_LOCATION_INVALID,
     258                location);
     259        return false;
     260    }
     261
     262    if (location == PS_LIST_TAIL) {
     263        // insert the element at the end of the list
     264        return psListAddAfter(list->iterators->data[0],data);
     265    } else {
     266        return psListAddBefore(list->iterators->data[0],data);
     267    }
     268}
     269
     270bool psListAddAfter(psListIterator* iterator, void* data)
     271{
     272    if (data == NULL) {
     273        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     274                PS_ERRORTEXT_psList_DATA_NULL);
     275        return false;
     276    }
     277
     278    if (iterator == NULL) {
     279        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     280                PS_ERRORTEXT_psList_ITERATOR_NULL);
     281        return false;
     282    }
     283
     284    psListElem* cursor = iterator->cursor;
     285
     286    if (cursor == NULL) {
     287        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     288                PS_ERRORTEXT_psList_ITERATOR_INVALID);
     289        return false;
     290    }
     291
     292    psList* list = iterator->list;
     293    psListElem* elem = psAlloc(sizeof(psListElem));
     294
     295    pthread_mutex_lock(&list->lock)
     296    ;
     297
     298    // set the new list element's attributes
     299    elem->prev = cursor;
     300    elem->next = cursor->next;
     301    elem->data = data;
     302
     303    cursor->next = elem;
     304    list->size++;
     305
     306    if (cursor == list->tail) {
     307        list->tail = elem;
     308    }
     309
     310    psArray* iterators = list->iterators;
     311    int index = iterator->index;
     312    for (int i = 0; i < iterators->n; i++) {
     313        psListIterator* iter = (psListIterator*) iterators->data[i];
     314        if (iter->index > index) {
     315            iter->index++;
     316        }
    238317    }
    239318
     
    241320    ;
    242321
    243     // OK, delete list element and its data
    244     psFree(elem->data);
    245     psFree(elem);
    246 
    247322    return true;
    248323}
    249324
    250 void psListSetIterator(psList* list, psS32 where)
    251 {
    252     listSetIterator(list, where, true);
    253 }
    254 
    255 static void listSetIterator(psList* list, psS32 where, psBool lockList)
    256 {
    257     psListElem* cursor;
    258     psS32 position;
    259 
     325bool psListAddBefore(psListIterator* iterator, void* data)
     326{
     327    if (data == NULL) {
     328        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     329                PS_ERRORTEXT_psList_DATA_NULL);
     330        return false;
     331    }
     332
     333    if (iterator == NULL) {
     334        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     335                PS_ERRORTEXT_psList_ITERATOR_NULL);
     336        return false;
     337    }
     338
     339    psListElem* cursor = iterator->cursor;
     340
     341    if (cursor == NULL) {
     342        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     343                PS_ERRORTEXT_psList_ITERATOR_INVALID);
     344        return false;
     345    }
     346
     347    psList* list = iterator->list;
     348    psListElem* elem = psAlloc(sizeof(psListElem));
     349
     350    pthread_mutex_lock(&list->lock)
     351    ;
     352
     353    // set the new list element's attributes
     354    elem->prev = cursor->prev;
     355    elem->next = cursor;
     356    elem->data = data;
     357
     358    cursor->prev = elem;
     359    list->size++;
     360
     361    if (cursor == list->head) {
     362        list->head = elem;
     363    }
     364
     365    psArray* iterators = list->iterators;
     366    int index = iterator->index;
     367    for (int i = 0; i < iterators->n; i++) {
     368        psListIterator* iter = (psListIterator*) iterators->data[i];
     369        if (iter->index >= index) {
     370            iter->index++;
     371        }
     372    }
     373
     374    pthread_mutex_unlock(&list->lock)
     375    ;
     376
     377    return true;
     378}
     379
     380psBool psListRemove(psList* list,
     381                    psS32 location)
     382{
    260383    if (list == NULL) {
    261384        psError(PS_ERR_BAD_PARAMETER_NULL, true,
    262                 "Unexpected null pointer for psList parameter.");
    263         return;
    264     }
    265 
    266     if (where == PS_LIST_CURRENT) {
    267         return;
    268     }
    269 
    270     if (lockList) {
    271         pthread_mutex_lock(&list->lock)
    272         ;
    273         // don't want the list changing on us while we move about
    274     }
    275 
    276     if (where >= (psS32)list->size) {
    277         list->p_iter = NULL;
    278         if (lockList) {
    279             pthread_mutex_unlock(&list->lock)
    280             ;
    281         }
    282         return;
    283     }
    284 
    285     switch (where) {
    286     case PS_LIST_HEAD:
    287         list->p_iter = ITER_INIT_HEAD;
    288         break;
    289 
    290     case PS_LIST_TAIL:
    291         list->p_iter = ITER_INIT_TAIL;
    292         break;
    293 
    294     case PS_LIST_PREVIOUS:
    295         cursor = listGetIterator(list);
    296         position = listGetIteratorIndex(list);
    297 
    298         if (cursor != NULL) {
    299             list->p_iter = cursor->prev;
    300             list->p_iterIndex = position - 1;
    301         }
    302         break;
    303 
    304     case PS_LIST_NEXT:
    305         cursor = listGetIterator(list);
    306         position = listGetIteratorIndex(list);
    307 
    308         if (cursor != NULL) {
    309             list->p_iter = cursor->next;
    310             list->p_iterIndex = position + 1;
    311         }
    312         break;
    313 
    314     case PS_LIST_CURRENT:
    315         break;
    316 
    317     default:
    318         if (where <= PS_LIST_HEAD) {   // bascially same as PS_LIST_UNKNOWN above
    319             psError(PS_ERR_BAD_PARAMETER_VALUE, true,
    320                     "Can't move to an unknown position.  Not moving the iterator position.");
    321         } else {
    322             cursor = listGetIterator(list);
    323             if (cursor == NULL) {      // reset the iterator if it is invalid
    324                 list->p_iter = ITER_INIT_HEAD;
    325                 list->p_iterIndex = 0;
    326             }
    327 
    328             psS32 position = listGetIteratorIndex(list);
    329 
    330             if (where < position) {
    331                 psS32 diff = position - where;
    332 
    333                 for (psS32 count = 0; count < diff; count++) {
    334                     listSetIterator(list, PS_LIST_PREVIOUS, false);
    335                 }
    336             } else {
    337                 psS32 diff = where - position;
    338 
    339                 for (psS32 count = 0; count < diff; count++) {
    340                     listSetIterator(list, PS_LIST_NEXT, false);
    341                 }
    342             }
    343         }
    344         break;
    345     }
    346 
    347     if (lockList) {
    348         pthread_mutex_unlock(&list->lock)
    349         ;
    350     }
    351 }
    352 
    353 psListElem* listGetIterator(psList* list)
     385                PS_ERRORTEXT_psList_LIST_NULL);
     386        return false;
     387    }
     388
     389    // move ourselves to the given position
     390    psListIterator* defaultIterator = list->iterators->data[0];
     391    if (list->iterators->n < 1 ||
     392            ! psListIteratorSet(defaultIterator,location)) {
     393        // oh no, I can't find where to add this!
     394        psError(PS_ERR_UNKNOWN, false,
     395                PS_ERRORTEXT_psList_LOCATION_INVALID,
     396                location);
     397        return false;
     398    }
     399
     400    return listIteratorRemove(defaultIterator);
     401}
     402
     403psBool psListRemoveData(psList* list,
     404                        psPtr data)
    354405{
    355406    if (list == NULL) {
     407        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     408                PS_ERRORTEXT_psList_LIST_NULL);
     409        return false;
     410    }
     411
     412    if (data == NULL) {
     413        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     414                PS_ERRORTEXT_psList_DATA_NULL);
     415        return false;
     416    }
     417
     418    psListIterator* iterator = list->iterators->data[0];
     419    psListIteratorSet(iterator,PS_LIST_HEAD);
     420
     421    psPtr iteratorData = psListGetNext(iterator);
     422    while (iteratorData != NULL && iteratorData != data) {
     423        iteratorData = psListGetNext(iterator);
     424    }
     425
     426    if (iteratorData == NULL) {
     427        psError(PS_ERR_BAD_PARAMETER_NULL, true,
     428                PS_ERRORTEXT_psList_DATA_NOT_FOUND);
     429        return false;
     430    }
     431
     432    return listIteratorRemove(iterator);
     433}
     434
     435psPtr psListGet(psList* list, psS32 location)
     436{
     437    psListIterator* iterator = list->iterators->data[0];
     438
     439    if (! psListIteratorSet(iterator,location)) {
     440        psError(PS_ERR_BAD_PARAMETER_VALUE, true,
     441                PS_ERRORTEXT_psList_LOCATION_INVALID,
     442                location);
    356443        return NULL;
    357444    }
    358445
    359     if (list->p_iter == ITER_INIT_HEAD) {
    360         return list->head;
    361     } else if (list->p_iter == ITER_INIT_TAIL) {
    362         return list->tail;
    363     } else {
    364         return list->p_iter;
    365     }
    366 }
    367 
    368 psS32 listGetIteratorIndex(psList* list)
    369 {
    370     if (list->p_iter == ITER_INIT_HEAD) {
    371         return 0;
    372     } else if (list->p_iter == ITER_INIT_TAIL) {
    373         return list->size - 1;
    374     } else {
    375         return list->p_iterIndex;
    376     }
    377 }
    378 
    379 psPtr psListGet(psList* list, psS32 location)
    380 {
    381     psListElem* element;
    382 
    383     psListSetIterator(list, location);
    384     element = listGetIterator(list);
    385 
    386     if (element == NULL) {
    387         return NULL;
    388     } else {
    389         return element->data;
    390     }
     446    return iterator->cursor->data;
    391447}
    392448
     
    394450 * and now return the previous/next element of the list
    395451 */
    396 psPtr psListGetNext(psList* list)
    397 {
    398     return psListGet(list, PS_LIST_NEXT);
    399 }
    400 
    401 psPtr psListGetPrevious(psList* list)
    402 {
    403     return psListGet(list, PS_LIST_PREVIOUS);
    404 }
    405 
    406 psPtr psListGetCurrent(psList* list)
    407 {
    408     return psListGet(list, PS_LIST_CURRENT);
     452psPtr psListGetNext(psListIterator* iterator)
     453{
     454    if (iterator == NULL || iterator->cursor == NULL) {
     455        return NULL;
     456    }
     457
     458    psPtr data = iterator->cursor->data;
     459
     460    iterator->cursor = iterator->cursor->next;
     461    iterator->index++;
     462    if (iterator->cursor == NULL) {
     463        iterator->offEnd = true;
     464    }
     465
     466    return data;
     467}
     468
     469psPtr psListGetPrevious(psListIterator* iterator)
     470{
     471    if (iterator == NULL || iterator->cursor == NULL) {
     472        return NULL;
     473    }
     474
     475    psPtr data = iterator->cursor->data;
     476
     477    iterator->cursor = iterator->cursor->prev;
     478    iterator->index--;
     479
     480    return data;
    409481}
    410482
     
    467539    // convert to indexable vector for use by qsort.
    468540    arr = psListToArray(list);
     541    psArray* iterators = psMemIncrRefCounter(list->iterators);
    469542    psFree(list);
    470543
     
    473546    // convert back to linked list
    474547    list = psArrayToList(arr);
     548    psFree(list->iterators);
     549    list->iterators = iterators;
    475550    psFree(arr);
    476551
     552    // sorting should invalidate all iterator positions.
     553    for (int i = 0; i < iterators->n; i++) {
     554        ((psListIterator*)iterators->data[i])->cursor = NULL;
     555    }
     556
    477557    return list;
    478558}
  • trunk/psLib/src/collections/psList.h

    r2375 r2681  
    1010 *  @ingroup LinkedList
    1111 *
    12  *  @version $Revision: 1.17 $ $Name: not supported by cvs2svn $
    13  *  @date $Date: 2004-11-16 20:00:20 $
     12 *  @version $Revision: 1.18 $ $Name: not supported by cvs2svn $
     13 *  @date $Date: 2004-12-10 02:50:14 $
    1414 *
    1515 *  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    3434    PS_LIST_HEAD = 0,                  ///< at head
    3535    PS_LIST_TAIL = -1,                 ///< at tail
    36     PS_LIST_PREVIOUS = -2,             ///< previous element
    37     PS_LIST_CURRENT = -3,              ///< current element
    38     PS_LIST_NEXT = -4,                 ///< next element
    39     PS_LIST_UNKNOWN = -5               ///< unknown position (should be last in enum list)
    4036};
    4137
     
    5955    psListElem* head;                  ///< first element on list (may be NULL)
    6056    psListElem* tail;                  ///< last element on list (may be NULL)
    61     psArray* iterators;                ///< iterators
     57    psArray* iterators;
     58    ///< array of all iterators associated with this list.  First iterator is
     59    ///< used internally to improve performance when using indexed access, all
     60    ///< others are user-level iterators created by psListIteratorAlloc.
     61
    6262    pthread_mutex_t lock;              ///< mutex to lock a node during changes
    63 psListElem* p_iter;                ///< internal cursor for increased performance index accessing
    64 int p_iterIndex;                   ///< index position of the iter.
    6563}
    6664psList;
     
    7775{
    7876psList* list;                      ///< List iterator to works on
    79 psU32 number;                      ///< List iterator number
    8077psListElem* cursor;                ///< current cursor position
     78int index;                         ///< the index number in the list
    8179bool offEnd;                       ///< Iterator off the end?
    8280}
     
    9492;
    9593
     94/** Creates a psListIterator object and associates it with a psList.
     95 *
     96 *  @return psListIterator* A new psListIterator object.
     97 */
     98psListIterator* psListIteratorAlloc(
     99    psList* list,                      ///< the psList to iterate with
     100    int location                       ///< the initial starting point.
     101    ///<  This can be a numeric index, PS_LIST_HEAD, or PS_LIST_TAIL.
     102);
     103
     104/** Set the iterator of the list to a given position.  If location is invalid the
     105 *  iterator position is not changed.
     106 *
     107 *  @return psBool        TRUE if iterator successfully set, otherwise FALSE.
     108 */
     109psBool psListIteratorSet(
     110    psListIterator* iterator,            ///< list iterator
     111    int location                         ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
     112);
     113
    96114/** Adds an element to a psList at position given.
    97115 *
    98  *  @return psList* The psList with added data item.  If list parameter is
    99  *                      NULL, the return value will also be NULL.
     116 *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
    100117 */
    101118psBool psListAdd(
    102     psList* restrict list,             ///< list to add to (if NULL, nothing is done)
    103     psS32 location,                      ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
     119    psList* restrict list,             ///< list to add item to
     120    psS32 location,                    ///< index, PS_LIST_HEAD, PS_LIST_TAIL, or numbered location.
    104121    psPtr data                         ///< data item to add.  If NULL, list is not modified.
    105122);
    106123
    107 /** Remove an item from a list.  If location parameter is PS_LIST_UNKNOWN,
     124/** Adds an data item to a psList at position just after the list position given
     125 *
     126 *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
     127 */
     128psBool psListAddAfter(
     129    psListIterator* list,              ///< list position to add item to
     130    psPtr data                         ///< data item to add.  If NULL, list is not modified.
     131);
     132
     133/** Adds an data item to a psList at position just before the list position given
     134 *
     135 *  @return psBool        TRUE if item was successfully added, otherwise FALSE.
     136 */
     137psBool psListAddBefore(
     138    psListIterator* list,              ///< list position to add item to
     139    psPtr data                         ///< data item to add.  If NULL, list is not modified.
     140);
     141
     142/** Remove an item at the specified location from a list.
    108143 *
    109144 *  @return psBool        TRUE if element is successfully removed, otherwise FALSE.
    110145 */
    111146psBool psListRemove(
    112     psList* restrict list,
    113     ///< list to remove element from
    114     psS32 location,
    115     ///< index of item, or PS_LIST_UNKNOWN, PS_LIST_NEXT, PS_LIST_PREV, or numbered location.
    116     psPtr data
    117     ///< if location is PS_LIST_UNKNOWN, data item to find and remove, otherwise this is ignored.
     147    psList* restrict list,             ///< list to remove element from
     148    psS32 location                     ///< index of item
     149);
     150
     151/** Remove an item from a list.
     152 *
     153 *  @return psBool        TRUE if element is successfully removed, otherwise FALSE.
     154 */
     155psBool psListRemoveData(
     156    psList* restrict list,             ///< list to remove element from
     157    psPtr data                         ///< data item to find and remove
    118158);
    119159
     
    127167psPtr psListGet(
    128168    psList* restrict list,             ///< list to retrieve element from
    129     psS32 location                       ///< index number, or PS_LIST_NEXT, PS_LIST_PREV, PS_LIST_UNKNOWN
    130 );
    131 
    132 /** Set the iterator of the list to a given position.  If location is invalid the
    133  *  iterator position is not changed.
    134  *
    135  */
    136 void psListSetIterator(
    137     psList* restrict list,             ///< list to retrieve element from
    138     psS32 location                       ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
    139 );
    140 
    141 /** Get next element relative to the iterator.  This also moves the iterator to
    142  *  the next list position.
    143  *
    144  *  @return psPtr       the data item next on the list or NULL if the iterator
    145  *                      is already pointing to the last element or the list
    146  *                      parameter was NULL.
     169    psS32 location                     ///< index number, PS_LIST_HEAD, or PS_LIST_TAIL
     170);
     171
     172/** Position the specified iterator to the next item in list.
     173 *
     174 *  @return psPtr       the data item at the new iterator position or NULL if the
     175 *                      iterator goes past the end of the list.
    147176 */
    148177psPtr psListGetNext(
    149     psList* restrict list              ///< list to retrieve element from
    150 );
    151 
    152 /** Get current element according to the psList's iterator cursor.  This does
    153  *  not move the iterator location.
    154  *
    155  *  @return psPtr       the data item cooresponding to current iterator
    156  *                      cursor position of the list, or NULL if either the
    157  *                      iterator is not valid or list parameter was NULL.
    158  */
    159 psPtr psListGetCurrent(
    160     psList* restrict list              ///< list to retrieve element from
    161 );
    162 
    163 /** Get previous element relative to list's iterator. This also moves the
    164  *  iterator to the previous list position.
    165  *
    166  *  @return psPtr       the data item previous on the list or NULL if the iterator
    167  *                      is already pointing to the first element or the list
    168  *                      parameter was NULL.
     178    psListIterator* restrict iterator  ///< iterator to move
     179);
     180
     181/** Position the specified iterator to the previous item in list.
     182 *
     183 *  @return psPtr       the data item at the new iterator position or NULL if the
     184 *                      iterator goes past the beginning of the list.
    169185 */
    170186psPtr psListGetPrevious(
    171     psList* restrict list              ///< list to retrieve element from
     187    psListIterator* restrict iterator  ///< iterator to move
    172188);
    173189
  • trunk/psLib/src/collections/psMetadata.c

    r2659 r2681  
    1212*  @author Ross Harman, MHPCC
    1313*
    14 *  @version $Revision: 1.42 $ $Name: not supported by cvs2svn $
    15 *  @date $Date: 2004-12-07 23:27:25 $
     14*  @version $Revision: 1.43 $ $Name: not supported by cvs2svn $
     15*  @date $Date: 2004-12-10 02:50:14 $
    1616*
    1717*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    352352{
    353353    psList* mdList = NULL;
    354     psList* entryList = NULL;
    355354    psHash* mdTable = NULL;
    356355    psMetadataItem* entry = NULL;
    357     psMetadataItem* entryChild = NULL;
    358356
    359357
     
    375373        }
    376374
    377         if (entry->type == PS_META_LIST) {
    378 
    379             // Table entry has children. Entry and children must be removed from metadata collection's list
    380             psListSetIterator(entryList, PS_LIST_HEAD);
    381             entryChild = psListGetCurrent(entryList);
    382             while(entryChild != NULL) {
    383                 if (!psListRemove(mdList, PS_LIST_UNKNOWN, entryChild)) {
    384                     psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
    385                     return false;
    386                 }
    387                 entryChild = psListGetNext(entryList);
    388             }
    389         } else {
    390 
    391             // Table entry has no children. Remove entry from metadata collection's list
    392             if (!psListRemove(mdList, PS_LIST_UNKNOWN, entry)) {
    393                 psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
    394                 return false;
    395             }
    396         }
    397         // Remove entry from metadata collection's table
    398         if (!psHashRemove(mdTable, key)) {
    399             psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
    400             return false;
    401         }
    402375    } else {
    403376
     
    414387            return false;
    415388        }
    416         // Use recursive remove, now that key is known
    417         psMetadataRemove(md, PS_LIST_UNKNOWN, key);
     389    }
     390
     391    if (!psListRemoveData(mdList, entry)) {
     392        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_LIST_FAILED, key);
     393        return false;
     394    }
     395
     396    // Remove entry from metadata collection's table
     397    if (!psHashRemove(mdTable, key)) {
     398        psError(PS_ERR_UNKNOWN, false, PS_ERRORTEXT_psMetadata_REMOVE_TABLE_FAILED, key);
     399        return false;
    418400    }
    419401
  • trunk/psLib/src/collections/psMetadataIO.c

    r2637 r2681  
    99*  @author Ross Harman, MHPCC
    1010*
    11 *  @version $Revision: 1.15 $ $Name: not supported by cvs2svn $
    12 *  @date $Date: 2004-12-06 19:59:57 $
     11*  @version $Revision: 1.16 $ $Name: not supported by cvs2svn $
     12*  @date $Date: 2004-12-10 02:50:14 $
    1313*
    1414*  Copyright 2004 Maui High Performance Computing Center, University of Hawaii
     
    1919#include <string.h>
    2020#include <ctype.h>
     21#include <limits.h>
    2122
    2223#include "psAbort.h"
     
    598599                if(metadataItem->type!=PS_META_LIST) {
    599600                    if(overwrite) {
    600                         psMetadataRemove(md, PS_LIST_UNKNOWN, strName);
     601                        psMetadataRemove(md, INT_MIN, strName);
    601602                    } else {
    602603                        (*nFail)++;
     
    790791    PS_PTR_CHECK_NULL_GENERAL(metadataItem, return);
    791792    PS_PTR_CHECK_NULL_GENERAL(metadataItem->data.list, return);
    792     psListSetIterator(metadataItem->data.list, PS_LIST_TAIL);
    793     metadataItem = (psMetadataItem*)psListGetCurrent(metadataItem->data.list);
     793    metadataItem = (psMetadataItem*)psListGet(metadataItem->data.list,PS_LIST_TAIL);
    794794    htAtts = (psHash*)metadataItem->data.list;
    795795    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
     
    848848            if(metadataItem->type != PS_META_LIST) {
    849849                if(overwrite) {
    850                     psMetadataRemove(md, PS_LIST_UNKNOWN, strName);
     850                    psMetadataRemove(md, INT_MIN, strName);
    851851                } else {
    852852                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
     
    943943    PS_PTR_CHECK_NULL_GENERAL(tables, return);
    944944    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
    945     psListSetIterator(tables->data.list, PS_LIST_TAIL);
    946     table = (psMetadataItem*)psListGetCurrent(tables->data.list);
     945    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
    947946    htAtts = (psHash*)table->data.list;
    948947    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
     
    10021001            if(metadataItem->type != PS_META_LIST) {
    10031002                if(overwrite) {
    1004                     psMetadataRemove(md, PS_LIST_UNKNOWN, strName);
     1003                    psMetadataRemove(md, INT_MIN, strName);
    10051004                } else {
    10061005                    psError(PS_ERR_IO, true, PS_ERRORTEXT_psMetadataIO_OVERWRITE_ITEM, strName, lineNumber,
     
    10451044    PS_PTR_CHECK_NULL_GENERAL(tables, return);
    10461045    PS_PTR_CHECK_NULL_GENERAL(tables->data.list, return);
    1047     psListSetIterator(tables->data.list, PS_LIST_TAIL);
    1048     table = (psMetadataItem*)psListGetCurrent(tables->data.list);
     1046    table = (psMetadataItem*)psListGet(tables->data.list,PS_LIST_TAIL);
    10491047    htAtts = (psHash*)table->data.list;
    10501048    PS_PTR_CHECK_NULL_GENERAL(htAtts, return);
     
    10701068
    10711069    // Free temporary metadata item and its hash table
    1072     psListRemove(tables->data.list, PS_LIST_TAIL, table);
     1070    psListRemove(tables->data.list, PS_LIST_TAIL);
    10731071
    10741072    psFree(psEndTagName);
Note: See TracChangeset for help on using the changeset viewer.