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