Changeset 11482


Ignore:
Timestamp:
Dec 5, 2010, 7:01:18 PM (11 years ago)
Author:
charles
Message:

(2.0x libtransmission) backport r11356 for #3678 "benc walking could be more efficient"

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2.0x/libtransmission/bencode.c

    r11480 r11482  
    924924};
    925925
    926 static struct SaveNode*
    927 nodeNewDict( const tr_benc * val )
     926static void
     927nodeInitDict( struct SaveNode * node, const tr_benc * val )
    928928{
    929929    int               i, j;
    930930    int               nKeys;
    931     struct SaveNode * node;
    932931    struct KeyIndex * indices;
    933932
     
    935934
    936935    nKeys = val->val.l.count / 2;
    937     node = tr_new0( struct SaveNode, 1 );
    938936    node->val = val;
    939937    node->children = tr_new0( int, nKeys * 2 );
     
    956954    assert( node->childCount == nKeys * 2 );
    957955    tr_free( indices );
    958     return node;
    959 }
    960 
    961 static struct SaveNode*
    962 nodeNewList( const tr_benc * val )
     956}
     957
     958static void
     959nodeInitList( struct SaveNode * node, const tr_benc * val )
    963960{
    964961    int               i, n;
    965     struct SaveNode * node;
    966962
    967963    assert( tr_bencIsList( val ) );
    968964
    969965    n = val->val.l.count;
    970     node = tr_new0( struct SaveNode, 1 );
    971966    node->val = val;
    972967    node->childCount = n;
     
    974969    for( i = 0; i < n; ++i ) /* a list's children don't need to be reordered */
    975970        node->children[i] = i;
    976 
    977     return node;
    978 }
    979 
    980 static struct SaveNode*
    981 nodeNewLeaf( const tr_benc * val )
    982 {
    983     struct SaveNode * node;
    984 
     971}
     972
     973static void
     974nodeInitLeaf( struct SaveNode * node, const tr_benc * val )
     975{
    985976    assert( !isContainer( val ) );
    986977
    987     node = tr_new0( struct SaveNode, 1 );
    988978    node->val = val;
    989     return node;
    990 }
    991 
    992 static struct SaveNode*
    993 nodeNew( const tr_benc * val )
    994 {
    995     struct SaveNode * node;
    996 
    997     if( tr_bencIsList( val ) )
    998         node = nodeNewList( val );
    999     else if( tr_bencIsDict( val ) )
    1000         node = nodeNewDict( val );
    1001     else
    1002         node = nodeNewLeaf( val );
    1003 
    1004     return node;
     979}
     980
     981static void
     982nodeInit( struct SaveNode * node, const tr_benc * val )
     983{
     984    static const struct SaveNode INIT_NODE = { NULL, 0, 0, 0, NULL };
     985    *node = INIT_NODE;
     986
     987         if( tr_bencIsList( val ) ) nodeInitList( node, val );
     988    else if( tr_bencIsDict( val ) ) nodeInitDict( node, val );
     989    else                            nodeInitLeaf( node, val );
    1005990}
    1006991
     
    10281013          void                   * user_data )
    10291014{
    1030     tr_ptrArray stack = TR_PTR_ARRAY_INIT;
    1031 
    1032     tr_ptrArrayAppend( &stack, nodeNew( top ) );
    1033 
    1034     while( !tr_ptrArrayEmpty( &stack ) )
     1015    int stackSize = 0;
     1016    int stackAlloc = 64;
     1017    struct SaveNode * stack = tr_new( struct SaveNode, stackAlloc );
     1018
     1019    nodeInit( &stack[stackSize++], top );
     1020
     1021    while( stackSize > 0 )
    10351022    {
    1036         struct SaveNode * node = tr_ptrArrayBack( &stack );
     1023        struct SaveNode * node = &stack[stackSize-1];
    10371024        const tr_benc *   val;
    10381025
     
    10511038            if( isContainer( node->val ) )
    10521039                walkFuncs->containerEndFunc( node->val, user_data );
    1053             tr_ptrArrayPop( &stack );
     1040            --stackSize;
    10541041            tr_free( node->children );
    1055             tr_free( node );
    10561042            continue;
    10571043        }
     
    10761062
    10771063                case TR_TYPE_LIST:
    1078                     if( val != node->val )
    1079                         tr_ptrArrayAppend( &stack, nodeNew( val ) );
    1080                     else
     1064                    if( val == node->val )
    10811065                        walkFuncs->listBeginFunc( val, user_data );
     1066                    else {
     1067                        if( stackAlloc == stackSize ) {
     1068                            stackAlloc *= 2;
     1069                            stack = tr_renew( struct SaveNode, stack, stackAlloc );
     1070                        }
     1071                        nodeInit( &stack[stackSize++], val );
     1072                    }
    10821073                    break;
    10831074
    10841075                case TR_TYPE_DICT:
    1085                     if( val != node->val )
    1086                         tr_ptrArrayAppend( &stack, nodeNew( val ) );
    1087                     else
     1076                    if( val == node->val )
    10881077                        walkFuncs->dictBeginFunc( val, user_data );
     1078                    else {
     1079                        if( stackAlloc == stackSize ) {
     1080                            stackAlloc *= 2;
     1081                            stack = tr_renew( struct SaveNode, stack, stackAlloc );
     1082                        }
     1083                        nodeInit( &stack[stackSize++], val );
     1084                    }
    10891085                    break;
    10901086
     
    10961092    }
    10971093
    1098     tr_ptrArrayDestruct( &stack, NULL );
     1094    tr_free( stack );
    10991095}
    11001096
     
    11741170
    11751171static void
    1176 freeDummyFunc( const tr_benc * val UNUSED,
    1177                void * buf          UNUSED  )
     1172freeDummyFunc( const tr_benc * val UNUSED, void * buf UNUSED  )
    11781173{}
    11791174
    11801175static void
    1181 freeStringFunc( const tr_benc * val,
    1182                 void *          freeme )
     1176freeStringFunc( const tr_benc * val, void * unused UNUSED )
    11831177{
    11841178    if( stringIsAlloced( val ) )
    1185         tr_ptrArrayAppend( freeme, val->val.s.str.ptr );
    1186 }
    1187 
    1188 static void
    1189 freeContainerBeginFunc( const tr_benc * val,
    1190                         void *          freeme )
    1191 {
    1192     tr_ptrArrayAppend( freeme, val->val.l.vals );
     1179        tr_free( val->val.s.str.ptr );
     1180}
     1181
     1182static void
     1183freeContainerEndFunc( const tr_benc * val, void * unused UNUSED )
     1184{
     1185    tr_free( val->val.l.vals );
    11931186}
    11941187
     
    11971190                                                freeDummyFunc,
    11981191                                                freeStringFunc,
    1199                                                 freeContainerBeginFunc,
    1200                                                 freeContainerBeginFunc,
    1201                                                 freeDummyFunc };
     1192                                                freeDummyFunc,
     1193                                                freeDummyFunc,
     1194                                                freeContainerEndFunc };
    12021195
    12031196void
     
    12051198{
    12061199    if( isSomething( val ) )
    1207     {
    1208         tr_ptrArray a = TR_PTR_ARRAY_INIT;
    1209         bencWalk( val, &freeWalkFuncs, &a );
    1210         tr_ptrArrayDestruct( &a, tr_free );
    1211     }
     1200        bencWalk( val, &freeWalkFuncs, NULL );
    12121201}
    12131202
Note: See TracChangeset for help on using the changeset viewer.