mirror of
https://github.com/EssentialsX/Essentials.git
synced 2024-11-18 08:35:44 +01:00
Calculation of /balancetop is now async to prevent slowdown of the server
This commit is contained in:
parent
7268e1965d
commit
eea7785b7f
@ -5,12 +5,10 @@ import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.collect.ConcurrentHashMultiset;
|
||||
import java.io.File;
|
||||
import java.util.HashSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.logging.Level;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
||||
@ -104,21 +102,9 @@ public class UserMap extends CacheLoader<String, User> implements IConf
|
||||
users.invalidate(name.toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
public Set<User> getAllUsers()
|
||||
public Set<String> getAllUniqueUsers()
|
||||
{
|
||||
final Set<User> userSet = new HashSet<User>();
|
||||
for (String name : keys)
|
||||
{
|
||||
try
|
||||
{
|
||||
userSet.add(users.get(name));
|
||||
}
|
||||
catch (ExecutionException ex)
|
||||
{
|
||||
Bukkit.getLogger().log(Level.INFO, "Failed to load user " + name, ex);
|
||||
}
|
||||
}
|
||||
return userSet;
|
||||
return Collections.unmodifiableSet(keys.elementSet());
|
||||
}
|
||||
|
||||
public int getUniqueUsers()
|
||||
|
@ -1,10 +1,10 @@
|
||||
package com.earth2me.essentials.commands;
|
||||
|
||||
import static com.earth2me.essentials.I18n._;
|
||||
import com.earth2me.essentials.User;
|
||||
import com.earth2me.essentials.Util;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
@ -15,6 +15,12 @@ public class Commandbalancetop extends EssentialsCommand
|
||||
{
|
||||
super("balancetop");
|
||||
}
|
||||
|
||||
private static final int CACHETIME = 5 * 60 * 1000;
|
||||
public static final int MINUSERS = 50;
|
||||
private static List<String> cache = new ArrayList<String>();
|
||||
private static long cacheage = 0;
|
||||
private static ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
|
||||
|
||||
@Override
|
||||
protected void run(final Server server, final CommandSender sender, final String commandLabel, final String[] args) throws Exception
|
||||
@ -24,7 +30,7 @@ public class Commandbalancetop extends EssentialsCommand
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Integer.parseInt(args[0]) < 10)
|
||||
if (Integer.parseInt(args[0]) < 19)
|
||||
{
|
||||
max = Integer.parseInt(args[0]);
|
||||
}
|
||||
@ -34,31 +40,141 @@ public class Commandbalancetop extends EssentialsCommand
|
||||
//catch it because they tried to enter a string not number.
|
||||
}
|
||||
}
|
||||
final Map<User, Double> balances = new HashMap<User, Double>();
|
||||
for (User u : ess.getUserMap().getAllUsers())
|
||||
|
||||
if (lock.readLock().tryLock())
|
||||
{
|
||||
balances.put(u, u.getMoney());
|
||||
try
|
||||
{
|
||||
if (cacheage > System.currentTimeMillis() - CACHETIME)
|
||||
{
|
||||
outputCache(sender, max);
|
||||
return;
|
||||
}
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS)
|
||||
{
|
||||
sender.sendMessage("Calculating results");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
ess.scheduleAsyncDelayedTask(new Viewer(sender, max));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ess.getUserMap().getUniqueUsers() > MINUSERS)
|
||||
{
|
||||
sender.sendMessage("Calculating results");
|
||||
}
|
||||
ess.scheduleAsyncDelayedTask(new Viewer(sender, max));
|
||||
}
|
||||
|
||||
final List<Map.Entry<User, Double>> sortedEntries = new ArrayList<Map.Entry<User, Double>>(balances.entrySet());
|
||||
Collections.sort(sortedEntries, new Comparator<Map.Entry<User, Double>>()
|
||||
{
|
||||
@Override
|
||||
public int compare(final Entry<User, Double> entry1, final Entry<User, Double> entry2)
|
||||
{
|
||||
return -entry1.getValue().compareTo(entry2.getValue());
|
||||
}
|
||||
});
|
||||
int count = 0;
|
||||
}
|
||||
|
||||
private static void outputCache(final CommandSender sender, int max)
|
||||
{
|
||||
sender.sendMessage(_("balanceTop", max));
|
||||
for (Map.Entry<User, Double> entry : sortedEntries)
|
||||
for (String line : cache)
|
||||
{
|
||||
if (count == max)
|
||||
if (max == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
sender.sendMessage(entry.getKey().getDisplayName() + ", " + Util.formatCurrency(entry.getValue(), ess));
|
||||
count++;
|
||||
max--;
|
||||
sender.sendMessage(line);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Calculator implements Runnable
|
||||
{
|
||||
private final transient Viewer viewer;
|
||||
|
||||
public Calculator(final Viewer viewer)
|
||||
{
|
||||
this.viewer = viewer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
lock.writeLock().lock();
|
||||
try
|
||||
{
|
||||
if (cacheage < System.currentTimeMillis() - 5 * 60 * 1000)
|
||||
{
|
||||
final Map<String, Double> balances = new HashMap<String, Double>();
|
||||
for (String u : ess.getUserMap().getAllUniqueUsers())
|
||||
{
|
||||
try
|
||||
{
|
||||
balances.put(u, ess.getUserMap().getUser(u).getMoney());
|
||||
}
|
||||
catch (NullPointerException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
final List<Map.Entry<String, Double>> sortedEntries = new ArrayList<Map.Entry<String, Double>>(balances.entrySet());
|
||||
Collections.sort(sortedEntries, new Comparator<Map.Entry<String, Double>>()
|
||||
{
|
||||
@Override
|
||||
public int compare(final Entry<String, Double> entry1, final Entry<String, Double> entry2)
|
||||
{
|
||||
return -entry1.getValue().compareTo(entry2.getValue());
|
||||
}
|
||||
});
|
||||
int count = 0;
|
||||
for (Map.Entry<String, Double> entry : sortedEntries)
|
||||
{
|
||||
if (count == 20)
|
||||
{
|
||||
break;
|
||||
}
|
||||
cache.add(entry.getKey() + ", " + Util.formatCurrency(entry.getValue(), ess));
|
||||
count++;
|
||||
}
|
||||
cacheage = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.writeLock().unlock();
|
||||
}
|
||||
ess.scheduleAsyncDelayedTask(viewer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class Viewer implements Runnable
|
||||
{
|
||||
private final transient CommandSender sender;
|
||||
private final transient int max;
|
||||
|
||||
public Viewer(final CommandSender sender, final int max)
|
||||
{
|
||||
this.sender = sender;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
lock.readLock().lock();
|
||||
try
|
||||
{
|
||||
if (cacheage > System.currentTimeMillis() - 5 * 60 * 1000)
|
||||
{
|
||||
outputCache(sender, max);
|
||||
return;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
lock.readLock().unlock();
|
||||
}
|
||||
ess.scheduleAsyncDelayedTask(new Calculator(new Viewer(sender, max)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user