Changeset 0d37c5b11c5226f990a48d4617f4b70527bb50b3
- Timestamp:
- 05/28/08 19:22:34
(3 months ago)
- Author:
- Rémi Denis-Courmont <rem@videolan.org>
- git-committer:
- Rémi Denis-Courmont <rem@videolan.org> 1211995354 +0300
- git-parent:
[620675d9d1a3580afb6913dedd642028ee4582eb]
- git-author:
- Rémi Denis-Courmont <rem@videolan.org> 1211995354 +0300
- Message:
Use a doubly-linked list for objects instead of a flat table
Speeds up object creation and deletion, slows down vlc_object_get (which
you should not use anyway, remember), makes no difference for the rest
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r620675d |
r0d37c5b |
|
| 150 | 150 | /* Object structure data */ |
|---|
| 151 | 151 | int i_counter; ///< object counter |
|---|
| 152 | | int i_objects; ///< Attached objects count |
|---|
| 153 | | vlc_object_t ** pp_objects; ///< Array of all objects |
|---|
| 154 | 152 | |
|---|
| 155 | 153 | module_bank_t * p_module_bank; ///< The module bank |
|---|
| … | … | |
| 185 | 183 | vlc_destructor_t pf_destructor; |
|---|
| 186 | 184 | |
|---|
| | 185 | /* Objects tree structure */ |
|---|
| | 186 | vlc_object_t *prev, *next; |
|---|
| 187 | 187 | vlc_object_t **pp_children; |
|---|
| 188 | 188 | int i_children; |
|---|
| r1c8c942 |
r0d37c5b |
|
| 73 | 73 | static void PrintObject ( vlc_object_t *, const char * ); |
|---|
| 74 | 74 | static void DumpStructure ( vlc_object_t *, int, char * ); |
|---|
| 75 | | static int FindIndex ( vlc_object_t *, vlc_object_t **, int ); |
|---|
| 76 | 75 | |
|---|
| 77 | 76 | static vlc_list_t * NewList ( int ); |
|---|
| … | … | |
| 142 | 141 | |
|---|
| 143 | 142 | p_libvlc_global->i_counter = 0; |
|---|
| 144 | | p_libvlc_global->i_objects = 0; |
|---|
| 145 | | p_libvlc_global->pp_objects = NULL; |
|---|
| | 143 | p_priv->next = p_priv->prev = p_new; |
|---|
| 146 | 144 | vlc_mutex_init( &structure_lock ); |
|---|
| 147 | 145 | } |
|---|
| … | … | |
| 172 | 170 | p_priv->pipes[0] = p_priv->pipes[1] = -1; |
|---|
| 173 | 171 | |
|---|
| | 172 | p_priv->next = VLC_OBJECT (p_libvlc_global); |
|---|
| 174 | 173 | vlc_mutex_lock( &structure_lock ); |
|---|
| | 174 | p_priv->prev = vlc_internals (p_libvlc_global)->prev; |
|---|
| | 175 | vlc_internals (p_libvlc_global)->prev = p_new; |
|---|
| | 176 | vlc_internals (p_priv->prev)->next = p_new; |
|---|
| 175 | 177 | p_new->i_object_id = p_libvlc_global->i_counter++; |
|---|
| 176 | | /* Wooohaa! If *this* fails, we're in serious trouble! Anyway it's |
|---|
| 177 | | * useless to try and recover anything if pp_objects gets smashed. */ |
|---|
| 178 | | TAB_APPEND( p_libvlc_global->i_objects, p_libvlc_global->pp_objects, |
|---|
| 179 | | p_new ); |
|---|
| 180 | 178 | vlc_mutex_unlock( &structure_lock ); |
|---|
| 181 | 179 | |
|---|
| … | … | |
| 341 | 339 | assert( p_global == vlc_global() ); |
|---|
| 342 | 340 | /* Test for leaks */ |
|---|
| 343 | | if( p_global->i_objects > 0 ) |
|---|
| 344 | | { |
|---|
| 345 | | int i; |
|---|
| 346 | | for( i = 0; i < p_global->i_objects; i++ ) |
|---|
| 347 | | { |
|---|
| 348 | | /* We are leaking this object */ |
|---|
| 349 | | fprintf( stderr, |
|---|
| 350 | | "ERROR: leaking object (id:%i, type:%s, name:%s)\n", |
|---|
| 351 | | p_global->pp_objects[i]->i_object_id, |
|---|
| 352 | | p_global->pp_objects[i]->psz_object_type, |
|---|
| 353 | | p_global->pp_objects[i]->psz_object_name ); |
|---|
| 354 | | |
|---|
| 355 | | /* Dump libvlc object to ease debugging */ |
|---|
| 356 | | vlc_object_dump( p_global->pp_objects[i] ); |
|---|
| 357 | | |
|---|
| 358 | | fflush(stderr); |
|---|
| 359 | | } |
|---|
| 360 | | |
|---|
| | 341 | for( vlc_object_t *leaked = p_priv->next; |
|---|
| | 342 | leaked != p_this; |
|---|
| | 343 | leaked = vlc_internals (leaked)->next ) |
|---|
| | 344 | { |
|---|
| | 345 | /* We are leaking this object */ |
|---|
| | 346 | fprintf( stderr, |
|---|
| | 347 | "ERROR: leaking object (id:%i, type:%s, name:%s)\n", |
|---|
| | 348 | leaked->i_object_id, leaked->psz_object_type, |
|---|
| | 349 | leaked->psz_object_name ); |
|---|
| | 350 | /* Dump libvlc object to ease debugging */ |
|---|
| | 351 | vlc_object_dump( leaked ); |
|---|
| | 352 | fflush(stderr); |
|---|
| | 353 | } |
|---|
| | 354 | |
|---|
| | 355 | if( p_priv->next != p_this ) |
|---|
| | 356 | { |
|---|
| 361 | 357 | /* Dump libvlc object to ease debugging */ |
|---|
| 362 | 358 | vlc_object_dump( p_this ); |
|---|
| 363 | | |
|---|
| 364 | 359 | /* Strongly abort, cause we want these to be fixed */ |
|---|
| 365 | 360 | abort(); |
|---|
| … | … | |
| 368 | 363 | |
|---|
| 369 | 364 | /* We are the global object ... no need to lock. */ |
|---|
| 370 | | free( p_global->pp_objects ); |
|---|
| 371 | | p_global->pp_objects = NULL; |
|---|
| 372 | | |
|---|
| 373 | 365 | vlc_mutex_destroy( &structure_lock ); |
|---|
| 374 | 366 | } |
|---|
| … | … | |
| 645 | 637 | void * vlc_object_get( int i_id ) |
|---|
| 646 | 638 | { |
|---|
| 647 | | int i_max, i_middle; |
|---|
| 648 | | vlc_object_t **pp_objects; |
|---|
| 649 | 639 | libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 650 | 640 | vlc_object_t *obj = NULL; |
|---|
| … | … | |
| 652 | 642 | vlc_mutex_lock( &structure_lock ); |
|---|
| 653 | 643 | |
|---|
| 654 | | pp_objects = p_libvlc_global->pp_objects; |
|---|
| 655 | | |
|---|
| 656 | | /* Perform our dichotomy */ |
|---|
| 657 | | for( i_max = p_libvlc_global->i_objects - 1 ; ; ) |
|---|
| 658 | | { |
|---|
| 659 | | i_middle = i_max / 2; |
|---|
| 660 | | |
|---|
| 661 | | if( pp_objects[i_middle]->i_object_id > i_id ) |
|---|
| 662 | | { |
|---|
| 663 | | i_max = i_middle; |
|---|
| 664 | | } |
|---|
| 665 | | else if( pp_objects[i_middle]->i_object_id < i_id ) |
|---|
| 666 | | { |
|---|
| 667 | | if( i_middle ) |
|---|
| 668 | | { |
|---|
| 669 | | pp_objects += i_middle; |
|---|
| 670 | | i_max -= i_middle; |
|---|
| 671 | | } |
|---|
| 672 | | else |
|---|
| 673 | | { |
|---|
| 674 | | /* This happens when there are only two remaining objects */ |
|---|
| 675 | | if( pp_objects[i_middle+1]->i_object_id == i_id ) |
|---|
| 676 | | { |
|---|
| 677 | | vlc_object_yield( pp_objects[i_middle+1] ); |
|---|
| 678 | | obj = pp_objects[i_middle+1]; |
|---|
| 679 | | } |
|---|
| 680 | | break; |
|---|
| 681 | | } |
|---|
| 682 | | } |
|---|
| 683 | | else |
|---|
| 684 | | { |
|---|
| 685 | | vlc_object_yield( pp_objects[i_middle] ); |
|---|
| 686 | | obj = pp_objects[i_middle]; |
|---|
| 687 | | break; |
|---|
| | 644 | for( obj = vlc_internals (p_libvlc_global)->next; |
|---|
| | 645 | obj != VLC_OBJECT (p_libvlc_global); |
|---|
| | 646 | obj = vlc_internals (obj)->next ) |
|---|
| | 647 | { |
|---|
| | 648 | if( obj->i_object_id == i_id ) |
|---|
| | 649 | { |
|---|
| | 650 | vlc_object_yield( obj ); |
|---|
| | 651 | return obj; |
|---|
| 688 | 652 | } |
|---|
| 689 | 653 | } |
|---|
| … | … | |
| 830 | 794 | if( b_should_destroy ) |
|---|
| 831 | 795 | { |
|---|
| 832 | | /* Remove the object from the table |
|---|
| | 796 | /* Remove the object from object list |
|---|
| 833 | 797 | * so that it cannot be encountered by vlc_object_get() */ |
|---|
| 834 | | libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 835 | | int i_index; |
|---|
| 836 | | |
|---|
| 837 | | i_index = FindIndex( p_this, p_libvlc_global->pp_objects, |
|---|
| 838 | | p_libvlc_global->i_objects ); |
|---|
| 839 | | REMOVE_ELEM( p_libvlc_global->pp_objects, |
|---|
| 840 | | p_libvlc_global->i_objects, i_index ); |
|---|
| | 798 | vlc_internals (internals->next)->prev = internals->prev; |
|---|
| | 799 | vlc_internals (internals->prev)->next = internals->next; |
|---|
| 841 | 800 | |
|---|
| 842 | 801 | /* Detach from parent to protect against FIND_CHILDREN */ |
|---|
| … | … | |
| 1024 | 983 | vlc_value_t oldval, vlc_value_t newval, void *p_data ) |
|---|
| 1025 | 984 | { |
|---|
| 1026 | | libvlc_global_data_t *p_libvlc_global = vlc_global(); |
|---|
| 1027 | | |
|---|
| 1028 | 985 | (void)oldval; (void)p_data; |
|---|
| 1029 | 986 | if( *psz_cmd == 'l' ) |
|---|
| 1030 | 987 | { |
|---|
| | 988 | vlc_object_t *root = VLC_OBJECT (vlc_global ()), *cur = root; |
|---|
| | 989 | |
|---|
| 1031 | 990 | vlc_mutex_lock( &structure_lock ); |
|---|
| 1032 | | |
|---|
| 1033 | | vlc_object_t **pp_current, **pp_end; |
|---|
| 1034 | | |
|---|
| 1035 | | pp_current = p_libvlc_global->pp_objects; |
|---|
| 1036 | | pp_end = pp_current + p_libvlc_global->i_objects; |
|---|
| 1037 | | |
|---|
| 1038 | | for( ; pp_current < pp_end ; pp_current++ ) |
|---|
| 1039 | | PrintObject( *pp_current, "" ); |
|---|
| 1040 | | |
|---|
| | 991 | do |
|---|
| | 992 | { |
|---|
| | 993 | PrintObject (cur, ""); |
|---|
| | 994 | cur = vlc_internals (cur)->next; |
|---|
| | 995 | } |
|---|
| | 996 | while (cur != root); |
|---|
| 1041 | 997 | vlc_mutex_unlock( &structure_lock ); |
|---|
| 1042 | 998 | } |
|---|
| … | … | |
| 1213 | 1169 | /* Following functions are local */ |
|---|
| 1214 | 1170 | |
|---|
| 1215 | | /***************************************************************************** |
|---|
| 1216 | | * FindIndex: find the index of an object in an array of objects |
|---|
| 1217 | | ***************************************************************************** |
|---|
| 1218 | | * This function assumes that p_this can be found in pp_objects. It will not |
|---|
| 1219 | | * crash if p_this cannot be found, but will return a wrong value. It is your |
|---|
| 1220 | | * duty to check the return value if you are not certain that the object could |
|---|
| 1221 | | * be found for sure. |
|---|
| 1222 | | *****************************************************************************/ |
|---|
| 1223 | | static int FindIndex( vlc_object_t *p_this, |
|---|
| 1224 | | vlc_object_t **pp_objects, int i_count ) |
|---|
| 1225 | | { |
|---|
| 1226 | | int i_middle = i_count / 2; |
|---|
| 1227 | | |
|---|
| 1228 | | if( i_count == 0 ) |
|---|
| 1229 | | { |
|---|
| 1230 | | return 0; |
|---|
| 1231 | | } |
|---|
| 1232 | | |
|---|
| 1233 | | if( pp_objects[i_middle] == p_this ) |
|---|
| 1234 | | { |
|---|
| 1235 | | return i_middle; |
|---|
| 1236 | | } |
|---|
| 1237 | | |
|---|
| 1238 | | if( i_count == 1 ) |
|---|
| 1239 | | { |
|---|
| 1240 | | return 0; |
|---|
| 1241 | | } |
|---|
| 1242 | | |
|---|
| 1243 | | /* We take advantage of the sorted array */ |
|---|
| 1244 | | if( pp_objects[i_middle]->i_object_id < p_this->i_object_id ) |
|---|
| 1245 | | { |
|---|
| 1246 | | return i_middle + FindIndex( p_this, pp_objects + i_middle, |
|---|
| 1247 | | i_count - i_middle ); |
|---|
| 1248 | | } |
|---|
| 1249 | | else |
|---|
| 1250 | | { |
|---|
| 1251 | | return FindIndex( p_this, pp_objects, i_middle ); |
|---|
| 1252 | | } |
|---|
| 1253 | | } |
|---|
| 1254 | | |
|---|
| 1255 | 1171 | static vlc_object_t * FindObject( vlc_object_t *p_this, int i_type, int i_mode ) |
|---|
| 1256 | 1172 | { |
|---|