RSS
 

Damn work! :)

10 Feb

Not much has gone on lately, except for the bad week start and then work has gone crazy, so I haven’t done much lately on my hobbies… Haven’t played SWTOR in ages, so I still haven’t had the time to finish all the questing so I can do an “early impressions” review…

Anyway, I took the opportunity to read up a lot on shading systems, specially multi-materials on a deferred rendering context, and I decided that when I have the chance, I’ll implement something like this: Anisotropic Lighting, combining a 3d texture to store the maps and a material id lookup (since I still have component free on the G-Buffer). Still not an ideal solution (since I can’t parameterized that much the materials, beyond the lookup… for example, I can’t parameterize rim-lighting with a falloff parameter, I have to fix that so I can generate the lighting lookup table). Anyway, it should give me some more flexibility in having different materials, specially on Grey

grey_anim03

The hair and fur shading seem “incorrect”, and this hopefully will allow me to fix it (with double-sided lighting for the hair and some anisotropy on the fur).

There’s a new blog post on Spellcaster Studios, showing some props and base textures for the terrain tiles, besides some explanation on how we’re going to make the terrain in the first episode.

Another thing that I’ve been working was with some SQL queries for work: I had a query that basically inserted some rows into a database, but it could only do that if there wasn’t some other rows there yet. Basically, I need to queue some reset commands, but could only do that if there wasn’t any pending reset commands…

First version just iterated and checked in PHP, and took about 15 seconds…

Then we built a query that did all that in one SQL query, and it took about 9 seconds (because it had to do a SELECT query for every hit in 1400+ rows)… Still too slow…

Finally, we just designed a series of statements with a different point of view… Instead of adding the new data and before adding it check if it was already present in a specific table (a query), we created a temporary table that had all the pending requests, and we just checked if the data we wanted to insert was in that table or not (a “static” structure)… Boom, down to 0.005 ms per query…

For fun, here’s the code:

CREATE TEMPORARY TABLE TempTable(
   key VARCHAR(50) NOT NULL
) ENGINE=MEMORY;

INSERT INTO TempTable(mac)
SELECT data FROM MainTable WHERE ((type=5) OR ((type=7) AND (error LIKE 
'processing%')));

INSERT INTO MainTable(id,user,status,type,data,error,comment,time) SELECT 
NULL,1,1,5,OtherTable.key,'','Device reset request (type=5)',NOW() 
FROM Services
INNER JOIN Addresses
ON Services.address=Addresses.id
INNER JOIN Devices
ON Services.device=Devices.id
INNER JOIN OtherTable
ON Devices.parameters=OtherTable.key
WHERE (Addresses.location=40) AND (Services.type=1) AND OtherTable.key 
NOT IN(SELECT key FROM TempTable);

DROP TABLE TempTable;

So, even something like SQL can be optimized! Smile (I really hate SQL and database programming, but this kind of things are quite neat!)

 
 

Tags: , ,

Leave a Reply

 
*

 
  1. lmgoes

    February 10, 2012 at 11:49 pm

    If you got 0.005ms, perhaps the query below may achieve slightly better results, since it doesn’t use temp tables and NOT IN clauses, and I believe it achieves the same desiring result. But If there are no stringent speed requirements and query performance is not the main driver for the application, then it’s not worth implementing this slight change. 🙂

    INSERT INTO MainTable(id,user,status,type,data,error,comment,time)
    SELECT NULL,1,1,5,OtherTable.key,”,’Device reset request (type=5)’,NOW()
    FROM Services
    INNER JOIN Addresses ON Services.address=Addresses.id
    INNER JOIN Devices ON Services.device=Devices.id
    INNER JOIN MainTable a ON Devices.parameters=a.data AND NOT((a.type=5) OR (a.type=7 AND a.error LIKE ‘processing%’))
    WHERE (Addresses.location=40) AND (Services.type=1)

     
    • Covenant

      February 15, 2012 at 1:57 pm

      I might be wrong there, but it doesn’t do exactly the same thing… I’ve tried it out, but it doesn’t create any rows when the table is empty… I’m guessing that happens because that new INNER JOIN doesn’t match with anything, so the SELECT becomes empty…

      So I clarify what I’m trying to achieve, I’m trying to control another application through the database…

      Let’s imagine I have a table (MainTable in the example above) in which each row is a command:

      | id | command | target | status |
      | 0 | stuff1 | target1 | processing |
      | 1 | stuff2 | target1 | done |

      Now, I want to do stuff1 to target1, but I just want to insert that if that isn’t being done yet… So, in the example above, it wouldn’t change the table, but in the example below it would:

      | id | command | target | status |
      | 0 | stuff1 | target1 | done: ok |
      | 1 | stuff2 | target1 | done: fail |

      With both queries, it does that, but with yours, the example below (table empty), it fails to insert stuff1 to target1:

      | id | command | target | status |

      With my query, that works… I might be seeing something wrong, since I had to adapt the query you gave to my specific case, but I think my initial conclusion stands: the “INNER JOIN MainTable a ON Devices.parameters=a.data AND NOT((a.type=5) OR (a.type=7 AND a.error LIKE ‘processing%’))” make the SELECT empty if the table is empty.

      This is not very important, as this isn’t something that happens that often (and 0.005ms is more than enough)… It just couldn’t take more than 5 seconds, since the HTTP connection between the GWT application and the PHP that actually does the query would timeout.