Efficiency question

Discussion in 'Plugin Development' started by GeorgeeeHD, Oct 13, 2014.

Thread Status:
Not open for further replies.
  1. Offline

    GeorgeeeHD

    I am currently developing a plugin that handles storing stats. The way I am currently doing it is with an SQL database that holds all the info and when the server loads up, I have a Stats class with a

    private static HashMap<UUID, Stats> stats;

    and it basically adds all players from the database into that map.

    What I want to know is if that way is more efficient than simply getting the data directly with a sql query or the current way.

    Thanks.
     
  2. Offline

    mythbusterma

    GeorgeeeHD

    Well the best way to do it is to stop abusing the "static" keyword, honestly.

    Beyond that, you should probably load the stats at startup, as an SQL query can take a non-determinate amount of time and requires the queries be run asynchronously, so it could present an issue depending on the speed at which the data is required.
     
    mine-care likes this.
  3. Offline

    mine-care

  4. Offline

    Konato_K

    mythbusterma Well, AsyncPlayerPreLoginEvent is async, the only problem is if the player gets kicked for being banned or other reason, but I guess listening on highest priority can solve that
     
  5. Offline

    coasterman10

    Abusing static won't affect performance, unless you're initializing it statically. But you still shouldn't abuse static. While I would use a static map to associate UUIDs with player data for example, I wouldn't use it to associate another variable if you already have a player data object. I would instead add a stats object to the player object.

    Stats should be done asynchronously. Even though there exist asynchronous login events, I would still recommend putting the SQL calls on a separate thread so the player does not have to wait for the SQL calls to finish before they get logged in.

    Make sure to use the correct concurrency models when using your map between multiple threads. A ConcurrentHashMap would be my first thought, but I am not an expert on concurrency.
     
    rbrick and ResultStatic like this.
  6. Offline

    ResultStatic

    mythbusterma there's nothing wrong with using static if you know what your doing. he has a reference stored of the Stats object. if he deletes the reference when the player leaves then the object will finalize like a normal object. i use a static hashmap<UUID,User> in my User class and it works great. the only thing that wont finalize is the hashmap which is like 20 bytes of data.
     
  7. Offline

    fireblast709

    Two things wrong with that:
    • Bans are handled in the PlayerLoginEvent, which fires after AsyncPlayerPreLoginEvent is handled.
    • Priority would only affect which listener gets the event first, not the order of how events themselves get handled (in other words, it won't change the order as stated in the first point.
    ResultStatic static is not conform with the OO principle encapsulation. For a more complete read, you could read Kitteh's sticky thread 'Common Mistakes', which features a stackoverflow link that goes in further detail.
     
  8. Offline

    Rocoty

    The idea is to future-proof your code. Making your map static makes you unable to subclass that class at a later point for another implementation of storing users etc. At least that's my main reason for being sparse with static.

    The point is, you don't know what you'll do in the future, and thus refraining from using static when you can is usually the best approach.
     
  9. Offline

    mythbusterma

    ResultStatic

    "If you know what you're doing," that really is the key point here isn't it? Since you don't know what you're doing, I would refer you to fireblast709 and Rocoty 's posts and expand by saying that it is also a crucial in separation of interface and implementation, as the fundamental concept of OOP is that the person accessing your class doesn't know/need to know how the internals work, directly exposing members by making them static is a failure in design, so I don't know what you're going on about this "finalizing" for, that feature of the language has been deprecated since 1.2, so I don't even know why you mention it, as garbage collection is a different concept to finalization and I never once said that statics prevent proper garbage collection, which it sometimes can.

    Furthermore coasterman10 I understand that doesn't affect performance, I was suggesting that he fix that so we can stop spreading this terrible practice.

    Konato_K I understand that a player login is asynchronous, however you missed the key point of my statement, that "an SQL query can take a non-determinate amount of time," meaning that the login would halt, and even be likely to timeout in the time it takes to run the query, if there was latency issues.

    Loading the values once at server start would be ideal if you're running this on a server without too many players (read: thousands), but if you are you can also spawn an asynchronous request on the player login event (or async login event) that requests the data and loads it, in which case a ConcurrentHashMap would be ideal for this (as coasterman10 suggested), as it would prevent synchronization issues and the likes, however the items contained inside the map still have to be be properly atomicized, in this case using a normal UUID object would be okay as the UUIDs are immutable (and would be easy to look up and store in SQL, as you can't use player names for this purpose) essentially, and mapping them to Atomic values that contain the score.
     
    Rocoty likes this.
  10. Offline

    Konato_K

    mythbusterma Well, the only problem I can see with loading everything on startup is if you have a insane amount of players, I have a plugin on a server with more than 150K rows, and well, I don't think loading that much is good.

    Also, I know lot of plugins that load all their data on startup and usually hang the whole server if can't connect to the database (this is just because they use the main thread)
     
  11. Offline

    JasonDL13

    Big sub.

    I would do this, and please correct me if this is a bad way. By - when the player joins, get the stats info of the player from the MySQL stuff, make it async ofc, and then when the player leaves, async a save thread to save the stats.
     
  12. Offline

    ResultStatic

    mythbusterma why would loading all the player data from an sql on startup be ideal? would'nt that waste a whole bunch of memory on players that may never even join the server again.
     
  13. Offline

    xTrollxDudex

    Because running it during normal plugin function can waste resources dedicated for more important tasks
     
  14. Offline

    GeorgeeeHD

    Assuming I did have 150k users, would this cause any problems?
     
Thread Status:
Not open for further replies.

Share This Page