Changeset 11356


Ignore:
Timestamp:
Oct 26, 2010, 7:30:35 PM (12 years ago)
Author:
charles
Message:

(trunk libT) #3678 "benc walking could be more efficient" -- fixed.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode.c

    r11300 r11356  
    942942};
    943943
    944 static struct SaveNode*
    945 nodeNewDict( const tr_benc * val )
     944static void
     945nodeInitDict( struct SaveNode * node, const tr_benc * val )
    946946{
    947947    int               i, j;
    948948    int               nKeys;
    949     struct SaveNode * node;
    950949    struct KeyIndex * indices;
    951950
     
    953952
    954953    nKeys = val->val.l.count / 2;
    955     node = tr_new0( struct SaveNode, 1 );
    956954    node->val = val;
    957955    node->children = tr_new0( int, nKeys * 2 );
     
    974972    assert( node->childCount == nKeys * 2 );
    975973    tr_free( indices );
    976     return node;
    977 }
    978 
    979 static struct SaveNode*
    980 nodeNewList( const tr_benc * val )
     974}
     975
     976static void
     977nodeInitList( struct SaveNode * node, const tr_benc * val )
    981978{
    982979    int               i, n;
    983     struct SaveNode * node;
    984980
    985981    assert( tr_bencIsList( val ) );
    986982
    987983    n = val->val.l.count;
    988     node = tr_new0( struct SaveNode, 1 );
    989984    node->val = val;
    990985    node->childCount = n;
     
    992987    for( i = 0; i < n; ++i ) /* a list's children don't need to be reordered */
    993988        node->children[i] = i;
    994 
    995     return node;
    996 }
    997 
    998 static struct SaveNode*
    999 nodeNewLeaf( const tr_benc * val )
    1000 {
    1001     struct SaveNode * node;
    1002 
     989}
     990
     991static void
     992nodeInitLeaf( struct SaveNode * node, const tr_benc * val )
     993{
    1003994    assert( !isContainer( val ) );
    1004995
    1005     node = tr_new0( struct SaveNode, 1 );
    1006996    node->val = val;
    1007     return node;
    1008 }
    1009 
    1010 static struct SaveNode*
    1011 nodeNew( const tr_benc * val )
    1012 {
    1013     struct SaveNode * node;
    1014 
    1015     if( tr_bencIsList( val ) )
    1016         node = nodeNewList( val );
    1017     else if( tr_bencIsDict( val ) )
    1018         node = nodeNewDict( val );
    1019     else
    1020         node = nodeNewLeaf( val );
    1021 
    1022     return node;
     997}
     998
     999static void
     1000nodeInit( struct SaveNode * node, const tr_benc * val )
     1001{
     1002    static const struct SaveNode INIT_NODE = { NULL, 0, 0, 0, NULL };
     1003    *node = INIT_NODE;
     1004
     1005         if( tr_bencIsList( val ) ) nodeInitList( node, val );
     1006    else if( tr_bencIsDict( val ) ) nodeInitDict( node, val );
     1007    else                            nodeInitLeaf( node, val );
    10231008}
    10241009
     
    10461031          void                   * user_data )
    10471032{
    1048     tr_ptrArray stack = TR_PTR_ARRAY_INIT;
    1049 
    1050     tr_ptrArrayAppend( &stack, nodeNew( top ) );
    1051 
    1052     while( !tr_ptrArrayEmpty( &stack ) )
     1033    int stackSize = 0;
     1034    int stackAlloc = 64;
     1035    struct SaveNode * stack = tr_new( struct SaveNode, stackAlloc );
     1036
     1037    nodeInit( &stack[stackSize++], top );
     1038
     1039    while( stackSize > 0 )
    10531040    {
    1054         struct SaveNode * node = tr_ptrArrayBack( &stack );
     1041        struct SaveNode * node = &stack[stackSize-1];
    10551042        const tr_benc *   val;
    10561043
     
    10691056            if( isContainer( node->val ) )
    10701057                walkFuncs->containerEndFunc( node->val, user_data );
    1071             tr_ptrArrayPop( &stack );
     1058            --stackSize;
    10721059            tr_free( node->children );
    1073             tr_free( node );
    10741060            continue;
    10751061        }
     
    10941080
    10951081                case TR_TYPE_LIST:
    1096                     if( val != node->val )
    1097                         tr_ptrArrayAppend( &stack, nodeNew( val ) );
    1098                     else
     1082                    if( val == node->val )
    10991083                        walkFuncs->listBeginFunc( val, user_data );
     1084                    else {
     1085                        if( stackAlloc == stackSize ) {
     1086                            stackAlloc *= 2;
     1087                            stack = tr_renew( struct SaveNode, stack, stackAlloc );
     1088                        }
     1089                        nodeInit( &stack[stackSize++], val );
     1090                    }
    11001091                    break;
    11011092
    11021093                case TR_TYPE_DICT:
    1103                     if( val != node->val )
    1104                         tr_ptrArrayAppend( &stack, nodeNew( val ) );
    1105                     else
     1094                    if( val == node->val )
    11061095                        walkFuncs->dictBeginFunc( val, user_data );
     1096                    else {
     1097                        if( stackAlloc == stackSize ) {
     1098                            stackAlloc *= 2;
     1099                            stack = tr_renew( struct SaveNode, stack, stackAlloc );
     1100                        }
     1101                        nodeInit( &stack[stackSize++], val );
     1102                    }
    11071103                    break;
    11081104
     
    11141110    }
    11151111
    1116     tr_ptrArrayDestruct( &stack, NULL );
     1112    tr_free( stack );
    11171113}
    11181114
     
    11921188
    11931189static void
    1194 freeDummyFunc( const tr_benc * val UNUSED,
    1195                void * buf          UNUSED  )
     1190freeDummyFunc( const tr_benc * val UNUSED, void * buf UNUSED  )
    11961191{}
    11971192
    11981193static void
    1199 freeStringFunc( const tr_benc * val,
    1200                 void *          freeme )
     1194freeStringFunc( const tr_benc * val, void * unused UNUSED )
    12011195{
    12021196    if( stringIsAlloced( val ) )
    1203         tr_ptrArrayAppend( freeme, val->val.s.str.ptr );
    1204 }
    1205 
    1206 static void
    1207 freeContainerBeginFunc( const tr_benc * val,
    1208                         void *          freeme )
    1209 {
    1210     tr_ptrArrayAppend( freeme, val->val.l.vals );
     1197        tr_free( val->val.s.str.ptr );
     1198}
     1199
     1200static void
     1201freeContainerEndFunc( const tr_benc * val, void * unused UNUSED )
     1202{
     1203    tr_free( val->val.l.vals );
    12111204}
    12121205
     
    12151208                                                freeDummyFunc,
    12161209                                                freeStringFunc,
    1217                                                 freeContainerBeginFunc,
    1218                                                 freeContainerBeginFunc,
    1219                                                 freeDummyFunc };
     1210                                                freeDummyFunc,
     1211                                                freeDummyFunc,
     1212                                                freeContainerEndFunc };
    12201213
    12211214void
     
    12231216{
    12241217    if( isSomething( val ) )
    1225     {
    1226         tr_ptrArray a = TR_PTR_ARRAY_INIT;
    1227         bencWalk( val, &freeWalkFuncs, &a );
    1228         tr_ptrArrayDestruct( &a, tr_free );
    1229     }
     1218        bencWalk( val, &freeWalkFuncs, NULL );
    12301219}
    12311220
Note: See TracChangeset for help on using the changeset viewer.