http-service: optimize bulk item price lookup
This commit is contained in:
@@ -28,11 +28,8 @@ import com.google.common.cache.Cache;
|
|||||||
import com.google.common.cache.CacheBuilder;
|
import com.google.common.cache.CacheBuilder;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
@@ -199,31 +196,20 @@ public class ItemController
|
|||||||
itemIds = Arrays.copyOf(itemIds, MAX_BATCH_LOOKUP);
|
itemIds = Arrays.copyOf(itemIds, MAX_BATCH_LOOKUP);
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<Integer> seen = new HashSet<>();
|
List<PriceEntry> prices = itemService.getPrices(itemIds);
|
||||||
List<ItemPrice> itemPrices = new ArrayList<>(itemIds.length);
|
|
||||||
for (int itemId : itemIds)
|
return prices.stream()
|
||||||
{
|
.map(priceEntry ->
|
||||||
if (seen.contains(itemId))
|
|
||||||
{
|
{
|
||||||
continue;
|
Item item = new Item();
|
||||||
}
|
item.setId(priceEntry.getItem()); // fake item
|
||||||
seen.add(itemId);
|
|
||||||
|
|
||||||
ItemEntry item = itemService.getItem(itemId);
|
ItemPrice itemPrice = new ItemPrice();
|
||||||
PriceEntry priceEntry = itemService.getPrice(itemId, null);
|
itemPrice.setItem(item);
|
||||||
|
itemPrice.setPrice(priceEntry.getPrice());
|
||||||
if (item == null || priceEntry == null)
|
itemPrice.setTime(priceEntry.getTime());
|
||||||
{
|
return itemPrice;
|
||||||
continue;
|
})
|
||||||
}
|
.toArray(ItemPrice[]::new);
|
||||||
|
|
||||||
ItemPrice itemPrice = new ItemPrice();
|
|
||||||
itemPrice.setItem(item.toItem());
|
|
||||||
itemPrice.setPrice(priceEntry.getPrice());
|
|
||||||
itemPrice.setTime(priceEntry.getTime());
|
|
||||||
itemPrices.add(itemPrice);
|
|
||||||
}
|
|
||||||
|
|
||||||
return itemPrices.toArray(new ItemPrice[itemPrices.size()]);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,8 +30,10 @@ import java.io.InputStream;
|
|||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
@@ -123,23 +125,57 @@ public class ItemService
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PriceEntry getPrice(Connection con, int itemId, Instant time)
|
||||||
|
{
|
||||||
|
if (time != null)
|
||||||
|
{
|
||||||
|
return con.createQuery("select item, price, time, fetched_time from prices where item = :item and time <= :time order by time desc limit 1")
|
||||||
|
.addParameter("item", itemId)
|
||||||
|
.addParameter("time", time.toString())
|
||||||
|
.executeAndFetchFirst(PriceEntry.class);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return con.createQuery("select item, price, time, fetched_time from prices where item = :item order by time desc limit 1")
|
||||||
|
.addParameter("item", itemId)
|
||||||
|
.executeAndFetchFirst(PriceEntry.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public PriceEntry getPrice(int itemId, Instant time)
|
public PriceEntry getPrice(int itemId, Instant time)
|
||||||
{
|
{
|
||||||
try (Connection con = sql2o.open())
|
try (Connection con = sql2o.open())
|
||||||
{
|
{
|
||||||
if (time != null)
|
return getPrice(con, itemId, time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<PriceEntry> getPrices(int... itemIds)
|
||||||
|
{
|
||||||
|
try (Connection con = sql2o.open())
|
||||||
|
{
|
||||||
|
Set<Integer> seen = new HashSet<>();
|
||||||
|
List<PriceEntry> priceEntries = new ArrayList<>(itemIds.length);
|
||||||
|
|
||||||
|
for (int itemId : itemIds)
|
||||||
{
|
{
|
||||||
return con.createQuery("select item, price, time, fetched_time from prices where item = :item and time <= :time order by time desc limit 1")
|
if (seen.contains(itemId))
|
||||||
.addParameter("item", itemId)
|
{
|
||||||
.addParameter("time", time.toString())
|
continue;
|
||||||
.executeAndFetchFirst(PriceEntry.class);
|
}
|
||||||
}
|
seen.add(itemId);
|
||||||
else
|
|
||||||
{
|
PriceEntry priceEntry = getPrice(con, itemId, null);
|
||||||
return con.createQuery("select item, price, time, fetched_time from prices where item = :item order by time desc limit 1")
|
|
||||||
.addParameter("item", itemId)
|
if (priceEntry == null)
|
||||||
.executeAndFetchFirst(PriceEntry.class);
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
priceEntries.add(priceEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return priceEntries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user