Improve item caching

- Add item composition cache and item search cache to ItemManager

Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
Tomas Slusny
2017-12-06 14:51:33 +01:00
committed by Adam
parent 6fac9d1d7b
commit 88932d2a72
3 changed files with 66 additions and 30 deletions

View File

@@ -36,9 +36,11 @@ import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import javax.inject.Singleton; import javax.inject.Singleton;
import net.runelite.api.Client; import net.runelite.api.Client;
import net.runelite.api.ItemComposition;
import net.runelite.api.SpritePixels; import net.runelite.api.SpritePixels;
import net.runelite.http.api.item.ItemClient; import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.SearchResult;
@Singleton @Singleton
public class ItemManager public class ItemManager
@@ -55,8 +57,10 @@ public class ItemManager
private final Client client; private final Client client;
private final ItemClient itemClient = new ItemClient(); private final ItemClient itemClient = new ItemClient();
private final LoadingCache<String, SearchResult> itemSearches;
private final LoadingCache<Integer, ItemPrice> itemPrices; private final LoadingCache<Integer, ItemPrice> itemPrices;
private final LoadingCache<Integer, BufferedImage> itemImages; private final LoadingCache<Integer, BufferedImage> itemImages;
private final LoadingCache<Integer, ItemComposition> itemCompositions;
@Inject @Inject
public ItemManager(@Nullable Client client, ScheduledExecutorService executor) public ItemManager(@Nullable Client client, ScheduledExecutorService executor)
@@ -67,6 +71,18 @@ public class ItemManager
.expireAfterAccess(1, TimeUnit.HOURS) .expireAfterAccess(1, TimeUnit.HOURS)
.build(new ItemPriceLoader(executor, itemClient)); .build(new ItemPriceLoader(executor, itemClient));
itemSearches = CacheBuilder.newBuilder()
.maximumSize(512L)
.expireAfterAccess(1, TimeUnit.HOURS)
.build(new CacheLoader<String, SearchResult>()
{
@Override
public SearchResult load(String key) throws Exception
{
return itemClient.search(key);
}
});
itemImages = CacheBuilder.newBuilder() itemImages = CacheBuilder.newBuilder()
.maximumSize(200) .maximumSize(200)
.expireAfterAccess(1, TimeUnit.HOURS) .expireAfterAccess(1, TimeUnit.HOURS)
@@ -78,15 +94,27 @@ public class ItemManager
return loadImage(itemId); return loadImage(itemId);
} }
}); });
itemCompositions = CacheBuilder.newBuilder()
.maximumSize(1024L)
.expireAfterAccess(1, TimeUnit.HOURS)
.build(new CacheLoader<Integer, ItemComposition>()
{
@Override
public ItemComposition load(Integer key) throws Exception
{
return client.getItemDefinition(key);
}
});
} }
/** /**
* Look up an item's price asynchronously. * Look up an item's price asynchronously.
* *
* @param itemId * @param itemId item id
* @return the price, or null if the price is not yet loaded * @return the price, or null if the price is not yet loaded
*/ */
public ItemPrice get(int itemId) public ItemPrice getItemPriceAsync(int itemId)
{ {
ItemPrice itemPrice = itemPrices.getIfPresent(itemId); ItemPrice itemPrice = itemPrices.getIfPresent(itemId);
if (itemPrice != null && itemPrice != EMPTY) if (itemPrice != null && itemPrice != EMPTY)
@@ -101,8 +129,8 @@ public class ItemManager
/** /**
* Look up an item's price synchronously * Look up an item's price synchronously
* *
* @param itemId * @param itemId item id
* @return * @return item price
* @throws IOException * @throws IOException
*/ */
public ItemPrice getItemPrice(int itemId) throws IOException public ItemPrice getItemPrice(int itemId) throws IOException
@@ -118,6 +146,30 @@ public class ItemManager
return itemPrice; return itemPrice;
} }
/**
* Look up an item's composition
*
* @param itemName item name
* @return item search result
* @throws java.util.concurrent.ExecutionException exception when item
* is not found
*/
public SearchResult searchForItem(String itemName) throws ExecutionException
{
return itemSearches.get(itemName);
}
/**
* Look up an item's composition
*
* @param itemId item id
* @return item composition
*/
public ItemComposition getItemComposition(int itemId)
{
return itemCompositions.getUnchecked(itemId);
}
/** /**
* Convert a quantity to stack size * Convert a quantity to stack size
* *

View File

@@ -33,6 +33,7 @@ import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -57,7 +58,6 @@ import net.runelite.http.api.hiscore.HiscoreSkill;
import net.runelite.http.api.hiscore.SingleHiscoreSkillResult; import net.runelite.http.api.hiscore.SingleHiscoreSkillResult;
import net.runelite.http.api.hiscore.Skill; import net.runelite.http.api.hiscore.Skill;
import net.runelite.http.api.item.Item; import net.runelite.http.api.item.Item;
import net.runelite.http.api.item.ItemClient;
import net.runelite.http.api.item.ItemPrice; import net.runelite.http.api.item.ItemPrice;
import net.runelite.http.api.item.SearchResult; import net.runelite.http.api.item.SearchResult;
@@ -71,7 +71,6 @@ public class ChatCommandsPlugin extends Plugin
private final String colKeyword = "<colRegular>"; private final String colKeyword = "<colRegular>";
private final String colKeywordHighLight = "<colHighlight>"; private final String colKeywordHighLight = "<colHighlight>";
private final ItemClient itemClient = new ItemClient();
private final HiscoreClient hiscoreClient = new HiscoreClient(); private final HiscoreClient hiscoreClient = new HiscoreClient();
private int transparancyVarbit = -1; private int transparancyVarbit = -1;
@@ -190,7 +189,7 @@ public class ChatCommandsPlugin extends Plugin
log.debug("Running price lookup for {}", search); log.debug("Running price lookup for {}", search);
executor.submit(() -> lookup(setMessage.getType(), setMessage.getMessageNode(), search)); executor.submit(() -> itemPriceLookup(setMessage.getType(), setMessage.getMessageNode(), search));
} }
else if (config.lvl() && message.toLowerCase().startsWith("!lvl") && message.length() > 5) else if (config.lvl() && message.toLowerCase().startsWith("!lvl") && message.length() > 5)
{ {
@@ -208,15 +207,15 @@ public class ChatCommandsPlugin extends Plugin
* @param messageNode The chat message containing the command. * @param messageNode The chat message containing the command.
* @param search The item given with the command. * @param search The item given with the command.
*/ */
private void lookup(ChatMessageType type, MessageNode messageNode, String search) private void itemPriceLookup(ChatMessageType type, MessageNode messageNode, String search)
{ {
SearchResult result; SearchResult result;
try try
{ {
result = itemClient.search(search); result = itemManager.searchForItem(search);
} }
catch (IOException ex) catch (ExecutionException ex)
{ {
log.warn("Unable to search for item {}", search, ex); log.warn("Unable to search for item {}", search, ex);
return; return;

View File

@@ -24,21 +24,17 @@
*/ */
package net.runelite.client.plugins.grounditems; package net.runelite.client.plugins.grounditems;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import javax.inject.Inject; import javax.inject.Inject;
import net.runelite.api.Client; import net.runelite.api.Client;
@@ -88,17 +84,6 @@ public class GroundItemsOverlay extends Overlay
private final Client client; private final Client client;
private final GroundItemsConfig config; private final GroundItemsConfig config;
private final StringBuilder itemStringBuilder = new StringBuilder(); private final StringBuilder itemStringBuilder = new StringBuilder();
private final LoadingCache<Integer, ItemComposition> itemCache = CacheBuilder.newBuilder()
.maximumSize(1024L)
.expireAfterAccess(1, TimeUnit.MINUTES)
.build(new CacheLoader<Integer, ItemComposition>()
{
@Override
public ItemComposition load(Integer key) throws Exception
{
return client.getItemDefinition(key);
}
});
@Inject @Inject
ItemManager itemManager; ItemManager itemManager;
@@ -186,7 +171,7 @@ public class GroundItemsOverlay extends Overlay
Item item = (Item) current; Item item = (Item) current;
int itemId = item.getId(); int itemId = item.getId();
int itemQuantity = item.getQuantity(); int itemQuantity = item.getQuantity();
ItemComposition itemDefinition = itemCache.getUnchecked(itemId); ItemComposition itemDefinition = itemManager.getItemComposition(itemId);
Integer currentQuantity = items.get(itemId); Integer currentQuantity = items.get(itemId);
if (!hiddenItems.contains(itemDefinition.getName().toLowerCase())) if (!hiddenItems.contains(itemDefinition.getName().toLowerCase()))
@@ -200,7 +185,7 @@ public class GroundItemsOverlay extends Overlay
? itemQuantity ? itemQuantity
: currentQuantity + itemQuantity; : currentQuantity + itemQuantity;
ItemPrice itemPrice = itemManager.get(itemId); ItemPrice itemPrice = itemManager.getItemPriceAsync(itemId);
int gePrice = itemPrice == null ? 0 : itemPrice.getPrice() * quantity; int gePrice = itemPrice == null ? 0 : itemPrice.getPrice() * quantity;
int alchPrice = Math.round(itemDefinition.getPrice() * HIGH_ALCHEMY_CONSTANT); int alchPrice = Math.round(itemDefinition.getPrice() * HIGH_ALCHEMY_CONSTANT);
@@ -230,7 +215,7 @@ public class GroundItemsOverlay extends Overlay
int itemId = itemIds.get(i); int itemId = itemIds.get(i);
int quantity = items.get(itemId); int quantity = items.get(itemId);
ItemComposition item = itemCache.getUnchecked(itemId); ItemComposition item = itemManager.getItemComposition(itemId);
if (item == null) if (item == null)
{ {
@@ -257,7 +242,7 @@ public class GroundItemsOverlay extends Overlay
} }
Color textColor = Color.WHITE; // Color to use when drawing the ground item Color textColor = Color.WHITE; // Color to use when drawing the ground item
ItemPrice itemPrice = itemManager.get(itemId); ItemPrice itemPrice = itemManager.getItemPriceAsync(itemId);
if (itemPrice != null && config.showGEPrice()) if (itemPrice != null && config.showGEPrice())
{ {
int cost = itemPrice.getPrice() * quantity; int cost = itemPrice.getPrice() * quantity;