Changeset 11780


Ignore:
Timestamp:
Jan 29, 2011, 6:14:35 PM (12 years ago)
Author:
jordan
Message:

(trunk libT) #33956 "tr_bencFree() could be faster" -- fixed.

benc requires its dictionaries to be represented in a sorted form, so we sort them before walking across the entries. However that's overkill when all we're doing is freeing memory, so this commit adds a mechanism in the benc walker to optionally avoid the sorting overhead.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libtransmission/bencode.c

    r11748 r11780  
    943943
    944944static void
    945 nodeInitDict( struct SaveNode * node, const tr_benc * val )
    946 {
    947     int               i, j;
    948     int               nKeys;
    949     struct KeyIndex * indices;
     945nodeInitDict( struct SaveNode * node, const tr_benc * val, tr_bool sort_dicts )
     946{
     947    int nKeys;
     948    const int n = val->val.l.count;
    950949
    951950    assert( tr_bencIsDict( val ) );
    952951
    953     nKeys = val->val.l.count / 2;
     952    nKeys = n / 2;
    954953    node->val = val;
    955954    node->children = tr_new0( int, nKeys * 2 );
    956955
    957     /* ugh, a dictionary's children have to be sorted by key... */
    958     indices = tr_new( struct KeyIndex, nKeys );
    959     for( i = j = 0; i < ( nKeys * 2 ); i += 2, ++j )
     956    if( sort_dicts )
    960957    {
    961         indices[j].key = getStr(&val->val.l.vals[i]);
    962         indices[j].index = i;
    963     }
    964     qsort( indices, j, sizeof( struct KeyIndex ), compareKeyIndex );
    965     for( i = 0; i < j; ++i )
     958        int i, j;
     959        struct KeyIndex * indices = tr_new( struct KeyIndex, nKeys );
     960        for( i=j=0; i<n; i+=2, ++j )
     961        {
     962            indices[j].key = getStr(&val->val.l.vals[i]);
     963            indices[j].index = i;
     964        }
     965        qsort( indices, j, sizeof( struct KeyIndex ), compareKeyIndex );
     966        for( i = 0; i < j; ++i )
     967        {
     968            const int index = indices[i].index;
     969            node->children[node->childCount++] = index;
     970            node->children[node->childCount++] = index + 1;
     971        }
     972
     973        tr_free( indices );
     974    }
     975    else
    966976    {
    967         const int index = indices[i].index;
    968         node->children[node->childCount++] = index;
    969         node->children[node->childCount++] = index + 1;
    970     }
    971 
    972     assert( node->childCount == nKeys * 2 );
    973     tr_free( indices );
     977        int i ;
     978
     979        for( i=0; i<n; ++i )
     980            node->children[node->childCount++] = i;
     981    }
     982
     983    assert( node->childCount == n );
    974984}
    975985
     
    9981008
    9991009static void
    1000 nodeInit( struct SaveNode * node, const tr_benc * val )
     1010nodeInit( struct SaveNode * node, const tr_benc * val, tr_bool sort_dicts )
    10011011{
    10021012    static const struct SaveNode INIT_NODE = { NULL, 0, 0, 0, NULL };
     
    10041014
    10051015         if( tr_bencIsList( val ) ) nodeInitList( node, val );
    1006     else if( tr_bencIsDict( val ) ) nodeInitDict( node, val );
     1016    else if( tr_bencIsDict( val ) ) nodeInitDict( node, val, sort_dicts );
    10071017    else                            nodeInitLeaf( node, val );
    10081018}
     
    10291039bencWalk( const tr_benc          * top,
    10301040          const struct WalkFuncs * walkFuncs,
    1031           void                   * user_data )
     1041          void                   * user_data,
     1042          tr_bool                  sort_dicts )
    10321043{
    10331044    int stackSize = 0;
     
    10351046    struct SaveNode * stack = tr_new( struct SaveNode, stackAlloc );
    10361047
    1037     nodeInit( &stack[stackSize++], top );
     1048    nodeInit( &stack[stackSize++], top, sort_dicts );
    10381049
    10391050    while( stackSize > 0 )
     
    10871098                            stack = tr_renew( struct SaveNode, stack, stackAlloc );
    10881099                        }
    1089                         nodeInit( &stack[stackSize++], val );
     1100                        nodeInit( &stack[stackSize++], val, sort_dicts );
    10901101                    }
    10911102                    break;
     
    10991110                            stack = tr_renew( struct SaveNode, stack, stackAlloc );
    11001111                        }
    1101                         nodeInit( &stack[stackSize++], val );
     1112                        nodeInit( &stack[stackSize++], val, sort_dicts );
    11021113                    }
    11031114                    break;
     
    12161227{
    12171228    if( isSomething( val ) )
    1218         bencWalk( val, &freeWalkFuncs, NULL );
     1229        bencWalk( val, &freeWalkFuncs, NULL, FALSE );
    12191230}
    12201231
     
    16061617    {
    16071618        case TR_FMT_BENC:
    1608             bencWalk( top, &saveFuncs, buf );
     1619            bencWalk( top, &saveFuncs, buf, TRUE );
    16091620            break;
    16101621
     
    16151626            data.out = buf;
    16161627            data.parents = NULL;
    1617             bencWalk( top, &jsonWalkFuncs, &data );
     1628            bencWalk( top, &jsonWalkFuncs, &data, TRUE );
    16181629            if( evbuffer_get_length( buf ) )
    16191630                evbuffer_add_printf( buf, "\n" );
Note: See TracChangeset for help on using the changeset viewer.