Hello There, Guest! Login or Register


LVP 2.93 - What needs to happen?
#1
http://trac.sa-mp.nl/lvp/ticket/300
http://trac.sa-mp.nl/lvp/ticket/127
http://trac.sa-mp.nl/lvp/ticket/305
http://trac.sa-mp.nl/lvp/ticket/306

These tickets definitly need to happen before we can update to LVP 2.93. This time everything has to be tested thoroughly on the main settings as well.

The entire gang system has to be checked for optimizing as well. If I forgot anything on the list or if you have a suggestion, please reply in this topic.

Matthias
Reply
#2
Fixed #305 already :)

I think before we work on these tickets we need to address the amount of queries and unoptimized functions contained within the user/gang handler.

* CheckUserExists - Function that gets called at least 3 times when a player connects, and once in the gang handler. This performs a query to clarify if a player is registered. This should only perform the query once and store the result in a variable. = DONE

* Profile IDs in the gang handler - This performs a query to determine a players profile ID and stores it to a variable when they connect in the gang handler. This already happens in the user handler and is stored to the PlayerInfo[playerid][playerProfile] variable, which we can use.

* Gang handler initialization. I'm going to quote the code for this:

Code:
#define     CUR_TURFS                     102

gangInitialize()
{
    for(new i; i < CUR_TURFS; i++)
    {
        CGang::T_WaitTimerOff(i);
        format(query, sizeof(query), "SELECT gang_id FROM turfs WHERE turf_id = %d", i);
        mysql_query(query);
        mysql_free_result();
        mysql_store_result();
        mysql_fetch_row_format(result);
        ActiveTurf[i][Owner] = strval(result);
...
}
That's performing 102 queries at once. I'm very surprised it doesn't bottleneck the server.

* CGang::PlayerConnect - This function is called from OnPlayerConnect and checks if a player is in a gang and updates all relevant information for the player. Surely this should be called when the player logs in!
- DONE

* mysql_free_result is called prior to every mysql_store_result function call. No idea why. - DONE

* CGang__GetNumberOfGangs() - This performs a query to get the result. Surely this can be stored in a variable.

* CGang__IsPlayerGangLeader(playerid) see above

* CGang__GetGangMoney(gangid) - see above
Reply
#3
[b]Before:[/b]

Code:
public CGang__ReloadGangData()
{
    new query[128], result[128];
    for(new i; i < MAX_GANGS; i++)
    {
        format(query, sizeof(query), "SELECT gang_name FROM gangs WHERE gang_id = %d", i);
        mysql_query(query);
        mysql_free_result();
        mysql_store_result();
       
        if(mysql_num_rows() > 0)
        {
            mysql_fetch_row_format(result);

            format(GangData[i][g_Name], 128, "%s", result);

            format(query, sizeof(query), "SELECT gang_color FROM gangs WHERE gang_id = %d", i);
            mysql_query(query);
            mysql_free_result();
            mysql_store_result();
            mysql_fetch_row_format(result);

            GangData[i][g_Color] = strval(result);

            #if GANG_HANDLER_DEBUG == 1
                printf("[Gang Handler Debug] Reloaded Gangdata (Gang ID: %d | Gang Name: %s | Gang Color: %d", i, GangData[i][g_Name], GangData[i][g_Color]);
            #endif
        }
    }
    
    return true;
}

* Performing 400 queries.
* Called in the initialization function which currently does another 300, totaling 700 queries on initialization.
* Called in 3 other gang commands.

[b]After:[/b]

Code:
public CGang__ReloadGangData( iPhase )
{
    // Threading - first phase.
    if(iPhase == 0)
    {
        mysql_query_callback(iPhase+1, "SELECT (gang_name, gang_color) FROM gangs", "CGang__ReloadGangData");
        // Query sent, now we wait until its finished before proceeding.
        return;
    }
   
    // query finished - continue

    mysql_store_result();
   
    // Any results?
    if(mysql_num_rows() == 0)
    {
        mysql_free_result();
        return;
    }
   
    new
        result[256],
        iGangID;

    // Alright, we loop through every result found and fetch the data.
    while(mysql_fetch_row_format(result))
    {
        // Quick bit of error checking - shouldn't be necessary though
        if(iGangID >= MAX_GANGS)
        {
            break;
        }

        // Format the gang name
        if(mysql_fetch_field_row(result, "gang_name"))
        {
            format(GangData[iGangID][g_Name], 128, "%s", result);
        }
        // don't forget the colour
        if(mysql_fetch_field_row(result, "gang_color"))
        {
            GangData[iGangID][g_Color] = strval(result);
        }

        // Increment the gang id and we're done!
        iGangID++;

        #if GANG_HANDLER_DEBUG == 1
            printf("[Gang Handler Debug] Reloaded Gang Data (Gang ID: %d | Gang Name: %s | Gang Color: %d", iGangID, GangData[iGangID][g_Name], GangData[iGangID][g_Color]);
        #endif

    }

    // All done!
    mysql_free_result();
}

* Performs 1, threaded query
* Is called only once, on initialization. No longer needs to be called from gang commands
* Probably about 500% faster



--

That's just an example of how one of the functions can be HIGHLY optimized. thiaZ, read and learn!


P.S Blame the forum for the indention
Reply
#4
(11-06-2010, 02:36 PM)Jay link Wrote: P.S Blame the forum for the indention
Why are you using tabs and spaces together?
Reply
#5
Just a copy + paste, habit I guess.
Reply