Expand chestaccess querying

Make a decison on whether or not to return chest access data based on the
BlockChangeType (ALL or CHESTACCESS) rather than partly on the block parameter
as these are the only two query types that don't enforce type != replaced

This is helpful because the list of blocks to request chest access for was
outdated and is duplicated in 3 different places, whereas the new method
will return whatever results have been logged regardless of type.

In addition, if the query type is CHESTACCESS (but not ALL), we can use
an alternate query that is vastly more efficient.  In tests (26 million
row log table, 400,000 row chest table) the query time for all chest results
was reduced from 30 seconds to 3.

Allows the chestaccess parameter to return data from the following inventory types:

- Brewing stand
- Trapped chest (fixes #483)
- Dropper
- Hopper
- Beacon

Note that this only affects lookup of logged items; the logging process has not
been touched, so #433 and similar have not been addressed

Also, update the list of valid container types, which will improve logging of
broken containers.
This commit is contained in:
Philip Cass
2013-11-07 13:51:02 +00:00
parent 7ac35e4698
commit 6025469dfa
4 changed files with 14 additions and 9 deletions

View File

@@ -406,7 +406,7 @@ public class CommandsHandler implements CommandExecutor
params.needPlayer = true;
if (params.types.isEmpty() || Block.inList(params.types, 63) || Block.inList(params.types, 68))
params.needSignText = true;
if (params.bct == BlockChangeType.CHESTACCESS || params.types.isEmpty() || Block.inList(params.types, 23) || Block.inList(params.types, 54) || Block.inList(params.types, 61) || Block.inList(params.types, 62))
if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL)
params.needChestAccess = true;
}
conn = logblock.getConnection();
@@ -466,7 +466,7 @@ public class CommandsHandler implements CommandExecutor
params.needPlayer = true;
if (params.types.isEmpty() || Block.inList(params.types, 63) || Block.inList(params.types, 68))
params.needSignText = true;
if (params.types.isEmpty() || Block.inList(params.types, 23) || Block.inList(params.types, 54) || Block.inList(params.types, 61) || Block.inList(params.types, 62))
if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL)
params.needChestAccess = true;
}
conn = logblock.getConnection();
@@ -538,9 +538,8 @@ public class CommandsHandler implements CommandExecutor
public void run() {
try {
params.needCoords = true;
if (params.bct == BlockChangeType.CHESTACCESS || params.types.isEmpty() || Block.inList(params.types, 23) || Block.inList(params.types, 54) || Block.inList(params.types, 61) || Block.inList(params.types, 62)) {
if (params.bct == BlockChangeType.CHESTACCESS || params.bct == BlockChangeType.ALL)
params.needChestAccess = true;
}
params.limit = 1;
params.sum = SummarizationMode.NONE;
conn = logblock.getConnection();

View File

@@ -120,7 +120,7 @@ public class Consumer extends TimerTask
/**
* @param container
* The respective container. Must be an instance of Chest, Dispencer or Furnace.
* The respective container. Must be an instance of an InventoryHolder.
*/
public void queueChestAccess(String playerName, BlockState container, short itemType, short itemAmount, byte itemData) {
if (!(container instanceof InventoryHolder))
@@ -130,7 +130,7 @@ public class Consumer extends TimerTask
/**
* @param type
* Type id of the container. Must be 63 or 68.
* Type id of the container.
*/
public void queueChestAccess(String playerName, Location loc, int type, short itemType, short itemAmount, byte itemData) {
queueBlock(playerName, loc, type, type, (byte)0, null, new ChestAccess(itemType, itemAmount, itemData));
@@ -140,7 +140,7 @@ public class Consumer extends TimerTask
* Logs a container block break. The block type before is assumed to be o (air). All content is assumed to be taken.
*
* @param container
* Must be instanceof InventoryHolder
* Must be an instance of InventoryHolder
*/
public void queueContainerBreak(String playerName, BlockState container) {
if (!(container instanceof InventoryHolder))

View File

@@ -141,7 +141,12 @@ public final class QueryParams implements Cloneable
if (needSignText)
from += "LEFT JOIN `" + getTable() + "-sign` USING (id) ";
if (needChestAccess)
from += "LEFT JOIN `" + getTable() + "-chest` USING (id) ";
// If BlockChangeType is CHESTACCESS, we can use more efficient query
if (bct == BlockChangeType.CHESTACCESS) {
from += "RIGHT JOIN `" + getTable() + "-chest` USING (id) ";
} else {
from += "LEFT JOIN `" + getTable() + "-chest` USING (id) ";
}
return select + " " + from + getWhere() + "ORDER BY date " + order + ", id " + order + " " + getLimit();
} else if (sum == SummarizationMode.TYPES)
return "SELECT type, SUM(created) AS created, SUM(destroyed) AS destroyed FROM ((SELECT type, count(*) AS created, 0 AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere(BlockChangeType.CREATED) + "GROUP BY type) UNION (SELECT replaced AS type, 0 AS created, count(*) AS destroyed FROM `" + getTable() + "` INNER JOIN `lb-players` USING (playerid) " + getWhere(BlockChangeType.DESTROYED) + "GROUP BY replaced)) AS t GROUP BY type ORDER BY SUM(created) + SUM(destroyed) " + order + " " + getLimit();
@@ -367,7 +372,6 @@ public final class QueryParams implements Cloneable
where.append("type != replaced AND ");
break;
case CHESTACCESS:
where.append("(type = 23 OR type = 54 OR type = 61 OR type = 62) AND type = replaced AND ");
if (!types.isEmpty()) {
where.append('(');
for (final Block block : types) {

View File

@@ -152,6 +152,8 @@ public class BukkitUtils
containerBlocks.add(Material.DROPPER);
containerBlocks.add(Material.HOPPER);
containerBlocks.add(Material.BREWING_STAND);
containerBlocks.add(Material.FURNACE);
containerBlocks.add(Material.BEACON);
// Doesn't actually have a block inventory
// containerBlocks.add(Material.ENDER_CHEST);
}