item manager: add batch item price lookup
This commit is contained in:
@@ -29,6 +29,10 @@ import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -36,6 +40,7 @@ import javax.annotation.Nullable;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Value;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.Client;
|
||||
import static net.runelite.api.Constants.CLIENT_DEFAULT_ZOOM;
|
||||
import net.runelite.api.ItemComposition;
|
||||
@@ -45,6 +50,7 @@ import net.runelite.http.api.item.ItemPrice;
|
||||
import net.runelite.http.api.item.SearchResult;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ItemManager
|
||||
{
|
||||
@Value
|
||||
@@ -58,17 +64,19 @@ public class ItemManager
|
||||
/**
|
||||
* not yet looked up
|
||||
*/
|
||||
|
||||
static final ItemPrice EMPTY = new ItemPrice();
|
||||
|
||||
/**
|
||||
* has no price
|
||||
*/
|
||||
static final ItemPrice NONE = new ItemPrice();
|
||||
|
||||
private final Client client;
|
||||
private final ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
private final ItemClient itemClient = new ItemClient();
|
||||
private final LoadingCache<String, SearchResult> itemSearches;
|
||||
private final LoadingCache<Integer, ItemPrice> itemPrices;
|
||||
private final LoadingCache<Integer, ItemPrice> itemPriceCache;
|
||||
private final LoadingCache<ImageKey, BufferedImage> itemImages;
|
||||
private final LoadingCache<Integer, ItemComposition> itemCompositions;
|
||||
|
||||
@@ -76,8 +84,10 @@ public class ItemManager
|
||||
public ItemManager(@Nullable Client client, ScheduledExecutorService executor)
|
||||
{
|
||||
this.client = client;
|
||||
itemPrices = CacheBuilder.newBuilder()
|
||||
.maximumSize(512L)
|
||||
this.scheduledExecutorService = executor;
|
||||
|
||||
itemPriceCache = CacheBuilder.newBuilder()
|
||||
.maximumSize(1024L)
|
||||
.expireAfterAccess(1, TimeUnit.HOURS)
|
||||
.build(new ItemPriceLoader(executor, itemClient));
|
||||
|
||||
@@ -126,16 +136,74 @@ public class ItemManager
|
||||
*/
|
||||
public ItemPrice getItemPriceAsync(int itemId)
|
||||
{
|
||||
ItemPrice itemPrice = itemPrices.getIfPresent(itemId);
|
||||
ItemPrice itemPrice = itemPriceCache.getIfPresent(itemId);
|
||||
if (itemPrice != null && itemPrice != EMPTY)
|
||||
{
|
||||
return itemPrice == NONE ? null : itemPrice;
|
||||
}
|
||||
|
||||
itemPrices.refresh(itemId);
|
||||
itemPriceCache.refresh(itemId);
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up bulk item prices asynchronously
|
||||
*
|
||||
* @param itemIds array of item Ids
|
||||
* @return a future called with the looked up prices
|
||||
*/
|
||||
public CompletableFuture<ItemPrice[]> getItemPriceBatch(List<Integer> itemIds)
|
||||
{
|
||||
final List<Integer> lookup = new ArrayList<>();
|
||||
final List<ItemPrice> existing = new ArrayList<>();
|
||||
for (int itemId : itemIds)
|
||||
{
|
||||
ItemPrice itemPrice = itemPriceCache.getIfPresent(itemId);
|
||||
if (itemPrice != null)
|
||||
{
|
||||
existing.add(itemPrice);
|
||||
}
|
||||
else
|
||||
{
|
||||
lookup.add(itemId);
|
||||
}
|
||||
}
|
||||
// All cached?
|
||||
if (lookup.isEmpty())
|
||||
{
|
||||
return CompletableFuture.completedFuture(existing.toArray(new ItemPrice[existing.size()]));
|
||||
}
|
||||
|
||||
final CompletableFuture<ItemPrice[]> future = new CompletableFuture<>();
|
||||
scheduledExecutorService.execute(() ->
|
||||
{
|
||||
try
|
||||
{
|
||||
// Do a query for the items not in the cache
|
||||
ItemPrice[] itemPrices = itemClient.lookupItemPrice(lookup.toArray(new Integer[lookup.size()]));
|
||||
if (itemPrices != null)
|
||||
{
|
||||
for (int itemId : lookup)
|
||||
{
|
||||
itemPriceCache.put(itemId, NONE);
|
||||
}
|
||||
for (ItemPrice itemPrice : itemPrices)
|
||||
{
|
||||
itemPriceCache.put(itemPrice.getItem().getId(), itemPrice);
|
||||
}
|
||||
// Append these to the already cached items
|
||||
Arrays.stream(itemPrices).forEach(existing::add);
|
||||
}
|
||||
future.complete(existing.toArray(new ItemPrice[existing.size()]));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
future.completeExceptionally(ex);
|
||||
}
|
||||
});
|
||||
return future;
|
||||
}
|
||||
|
||||
/**
|
||||
* Look up an item's price synchronously
|
||||
*
|
||||
@@ -145,7 +213,7 @@ public class ItemManager
|
||||
*/
|
||||
public ItemPrice getItemPrice(int itemId) throws IOException
|
||||
{
|
||||
ItemPrice itemPrice = itemPrices.getIfPresent(itemId);
|
||||
ItemPrice itemPrice = itemPriceCache.getIfPresent(itemId);
|
||||
if (itemPrice != null && itemPrice != EMPTY)
|
||||
{
|
||||
return itemPrice == NONE ? null : itemPrice;
|
||||
@@ -154,11 +222,11 @@ public class ItemManager
|
||||
itemPrice = itemClient.lookupItemPrice(itemId);
|
||||
if (itemPrice == null)
|
||||
{
|
||||
itemPrices.put(itemId, NONE);
|
||||
itemPriceCache.put(itemId, NONE);
|
||||
return null;
|
||||
}
|
||||
|
||||
itemPrices.put(itemId, itemPrice);
|
||||
itemPriceCache.put(itemId, itemPrice);
|
||||
return itemPrice;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user