Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 // -*- c++ -*-
     19 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     20 
     21 //               S O R T E D   L I S T   C L A S S
     22 
     23 // = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
     24 
     25 #ifndef __SORTED_LIST_H
     26 #define __SORTED_LIST_H
     27 
     28 // - - Inclusion - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     29 
     30 
     31 #include "oscl_mutex.h"
     32 
     33 
     34 const int LIST_DEBUG_ENABLE = 1;
     35 
     36 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
     37 template <class LLClass> class SortedList;
     38 
     39 template <class LLClass> class SortedListElement
     40 {
     41 
     42     public:
     43         SortedListElement(LLClass in_data)
     44         {
     45             data = in_data;
     46             next = NULL;
     47         };
     48 
     49         friend class SortedList<LLClass>;
     50 
     51     private:
     52         SortedListElement<LLClass>* next;
     53         LLClass data;
     54 };
     55 
     56 
     57 template <class LLClass> class SortedList
     58 {
     59 
     60     public:
     61         SortedList();
     62         ~SortedList();
     63 
     64         int add_element(const LLClass& new_data);
     65         int remove_element(LLClass& data_to_remove);
     66         int remove_element(const int index_to_remove);
     67         int get_index(const LLClass& data) const;
     68         int get_num_elements() const
     69         {
     70             return num_elements;
     71         };
     72         int get_element(LLClass& element) const ;
     73         int get_element(int index, LLClass& element) const;
     74 
     75 
     76         int dequeue_pre_element()
     77         {
     78 
     79         }
     80 
     81         int get_first(LLClass & element)
     82         {
     83             if (NULL == head) return 0;
     84             iterator = head;
     85             element = head->data;
     86 
     87             return 1;
     88         }
     89 
     90         int get_next(LLClass & element)
     91         {
     92             if (tail == iterator)
     93             {
     94                 return 0;
     95             }
     96             if (!iterator)
     97             {
     98                 if (!head) return 0;
     99                 iterator = head;
    100             }
    101             else
    102             {
    103                 iterator = iterator->next;
    104             }
    105             element = iterator->data;
    106             return 1;
    107         }
    108 
    109 
    110 
    111 
    112     private:
    113         SortedListElement<LLClass> *head;
    114         SortedListElement<LLClass> *tail;
    115         SortedListElement<LLClass> *iterator;
    116 
    117         int num_elements;
    118 
    119         int check_list();
    120 };
    121 
    122 
    123 template <class LLClass> SortedList<LLClass>::SortedList()
    124 {
    125     num_elements = 0;
    126     iterator = head = tail = NULL;
    127 }
    128 
    129 template <class LLClass> SortedList<LLClass>::~SortedList()
    130 {
    131     SortedListElement<LLClass>* tmp;
    132     while (num_elements && head)
    133     {
    134         tmp = head->next;
    135         OSCL_DELETE(head);
    136         --num_elements;
    137         head = tmp;
    138     }
    139     head = tail = NULL;
    140 }
    141 
    142 
    143 template <class LLClass> int SortedList<LLClass>::check_list()
    144 {
    145 
    146     SortedListElement<LLClass> *tmp;
    147     int ii;
    148 
    149     for (tmp = head, ii = 0; tmp ; ++ii, tmp = tmp->next);
    150 
    151     if (ii != num_elements)
    152     {
    153         // bark - number of elements (num_elements) does not match first null (ii)
    154     }
    155 
    156 
    157     return (ii == num_elements);
    158 
    159 
    160 }
    161 
    162 
    163 template <class LLClass> int SortedList<LLClass>::add_element(const LLClass& new_element)
    164 {
    165     if (!tail)
    166     {
    167         // empty so just add it at the end
    168         head = tail = OSCL_NEW(SortedListElement<LLClass>, (new_element));
    169     }
    170     else
    171     {
    172         // find the proper location in the list
    173         SortedListElement<LLClass> *prev;
    174         SortedListElement<LLClass> *cur;
    175         int ii;
    176         for (prev = NULL, cur = head, ii = 0; ii < num_elements && cur;
    177                 prev = cur, cur = cur->next, ++ii)
    178         {
    179             if (new_element <= cur->data)
    180             {
    181                 // add at the current location
    182                 if (prev)
    183                 {
    184                     prev->next = OSCL_NEW(SortedListElement<LLClass>, (new_element));
    185                     prev->next->next = cur;
    186                 }
    187                 else
    188                 {
    189                     // this is the new head
    190                     prev = OSCL_NEW(SortedListElement<LLClass>, (new_element));
    191                     prev->next = head;
    192                     head = prev;
    193                 }
    194                 break;
    195             }
    196         }
    197 
    198         if (ii >= num_elements)
    199         {
    200             // new element goes at the end
    201             tail->next = OSCL_NEW(SortedListElement<LLClass>, (new_element));
    202             tail = tail->next;
    203         }
    204     }
    205 
    206     ++num_elements;
    207     return 1;
    208 }
    209 
    210 
    211 template <class LLClass> int SortedList<LLClass>::get_element(int index, LLClass& element) const
    212 {
    213 
    214     SortedListElement<LLClass> *tmp;
    215     int ii;
    216 
    217     if (index < 0 || index >= num_elements)
    218     {
    219         return 0;
    220     }
    221 
    222     for (tmp = head, ii = 0; ii < index; ++ii, tmp = tmp->next);
    223 
    224     element = tmp->data;
    225     return 1;
    226 }
    227 
    228 
    229 template <class LLClass> int SortedList<LLClass>::get_element(LLClass& element) const
    230 {
    231 
    232     SortedListElement<LLClass> *tmp;
    233     int ii;
    234     int found = 0;
    235 
    236     for (tmp = head, ii = 0; ii < num_elements && tmp; ++ii, tmp = tmp->next)
    237     {
    238         if (element == tmp->data)
    239         {
    240             found  = 1;
    241             break;
    242         }
    243     }
    244     return found;
    245 }
    246 
    247 template <class LLClass> int SortedList<LLClass>::remove_element(LLClass& data_to_remove)
    248 {
    249     SortedListElement<LLClass> *tmp;
    250     SortedListElement<LLClass> *prev;
    251     int found = 0;
    252     int idx = 0;
    253 
    254     for (tmp = head, prev = NULL; tmp; prev = tmp, tmp = tmp->next)
    255     {
    256 
    257         if (tmp->data == data_to_remove)
    258         {
    259             found = 1;
    260             if (prev)
    261             {
    262                 prev->next = tmp->next;
    263                 if (iterator == tmp) iterator = prev;
    264             }
    265             else
    266             {
    267                 head = tmp->next;
    268                 if (iterator == tmp) iterator = NULL;
    269             }
    270             if (tmp == tail)
    271             {
    272                 tail = prev;
    273             }
    274 
    275 
    276             OSCL_DELETE(tmp);
    277             --num_elements;
    278             break;
    279         }
    280         else if (tmp->data > data_to_remove)
    281         {
    282             // not in the list
    283             break;
    284         }
    285         idx++;
    286     } // of for loop
    287     return found;
    288 }
    289 
    290 
    291 template <class LLClass> int SortedList<LLClass>::get_index(const LLClass& data) const
    292 {
    293     SortedListElement<LLClass> *tmp;
    294     int index = 0;
    295     int found = 0;
    296 
    297     for (tmp = head, index = 0; tmp; tmp = tmp->next, ++index)
    298     {
    299 
    300         if (tmp->data == data)
    301         {
    302             found = 1;
    303             break;
    304         }
    305         else if (tmp->data > data)
    306         {
    307             // not found
    308             break;
    309         }
    310     }
    311     if (found)
    312         return index;
    313 
    314     return -1;
    315 }
    316 
    317 
    318 
    319 template <class LLClass> int SortedList<LLClass>::remove_element(const int index_to_remove)
    320 {
    321     SortedListElement<LLClass> *tmp;
    322     SortedListElement<LLClass> *prev;
    323     int ii;
    324 
    325     if (index_to_remove < 0 || index_to_remove >= num_elements)
    326     {
    327         return 0;
    328     }
    329 
    330     // skip to desired element
    331     for (tmp = head, prev = NULL, ii = 0; tmp && ii < index_to_remove;
    332             ++ii, prev = tmp, tmp = tmp->next);
    333 
    334     if (ii != index_to_remove)
    335     {
    336         return 0;
    337     }
    338 
    339     if (prev)
    340     {
    341         prev->next = tmp->next;
    342         if (iterator == tmp) iterator = prev;
    343     }
    344     else
    345     {
    346         head = tmp->next;
    347         if (iterator == tmp) iterator = NULL;
    348     }
    349 
    350 
    351     if (tmp == tail)
    352     {
    353         tail = prev;
    354     }
    355 
    356 
    357     OSCL_DELETE(tmp);
    358     --num_elements;
    359 
    360 
    361     return 1;
    362 }
    363 
    364 
    365 // MTSortedList is a multi-threaded version of
    366 // the SortedList.  It has mutex protection to
    367 // allow access by different threads.
    368 
    369 
    370 template <class LLClass> class MTSortedList
    371 {
    372     public:
    373 
    374         MTSortedList() {};
    375         ~MTSortedList() {};
    376 
    377         int add_element(const LLClass& new_data);
    378         int remove_element(const LLClass& data_to_remove);
    379         int remove_element(const int index_to_remove);
    380         int get_index(const LLClass& data) const ;
    381         int get_num_elements() const
    382         {
    383             return the_list.get_num_elements();
    384         };
    385         int get_element(LLClass& element) const;
    386         int get_element(int index, LLClass& element) const ;
    387 
    388 
    389     private:
    390         SortedList<LLClass> the_list;
    391         PVMutex mutex;
    392 
    393 };
    394 
    395 
    396 
    397 template <class LLClass> int MTSortedList<LLClass>::add_element(const LLClass& new_element)
    398 {
    399     int status;
    400     mutex.Lock();
    401     status = the_list.add_element(new_element);
    402     mutex.Unlock();
    403     return status;
    404 }
    405 
    406 template <class LLClass> int MTSortedList<LLClass>::remove_element(const LLClass& data_to_remove)
    407 {
    408     int status;
    409 
    410     mutex.Lock();
    411     status = the_list.remove_element(data_to_remove);
    412     mutex.Unlock();
    413     return status;
    414 }
    415 
    416 
    417 template <class LLClass> int MTSortedList<LLClass>::remove_element(const int index_to_remove)
    418 {
    419     int status;
    420     mutex.Lock();
    421     status = the_list.remove_element(index_to_remove);
    422     mutex.Unlock();
    423     return status;
    424 }
    425 
    426 template <class LLClass> int MTSortedList<LLClass>::get_index(const LLClass& data) const
    427 {
    428     int status;
    429     mutex.Lock();
    430     status = the_list.get_index(data);
    431     mutex.Unlock();
    432     return status;
    433 }
    434 
    435 template <class LLClass> int MTSortedList<LLClass>::get_element(LLClass& element) const
    436 {
    437 
    438     int status;
    439     mutex.Lock();
    440     status = the_list.get_element(element);
    441     mutex.Unlock();
    442     return status;
    443 }
    444 
    445 
    446 template <class LLClass> int MTSortedList<LLClass>::get_element(int index, LLClass& element) const
    447 {
    448 
    449     int status;
    450     mutex.Lock();
    451     status = the_list.get_element(index, element);
    452     mutex.Unlock();
    453     return status;
    454 }
    455 
    456 
    457 
    458 
    459 
    460 
    461 
    462 
    463 
    464 
    465 
    466 #endif  // __SORTED_LIST_H
    467 
    468