http-service: optimize bulk item price lookup

This commit is contained in:
Adam
2018-05-13 08:39:20 -04:00
parent ede2041a61
commit 274c79a7ba
2 changed files with 60 additions and 38 deletions

View File

@@ -28,11 +28,8 @@ import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.time.Duration;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
@@ -199,31 +196,20 @@ public class ItemController
itemIds = Arrays.copyOf(itemIds, MAX_BATCH_LOOKUP);
}
Set<Integer> seen = new HashSet<>();
List<ItemPrice> itemPrices = new ArrayList<>(itemIds.length);
for (int itemId : itemIds)
{
if (seen.contains(itemId))
List<PriceEntry> prices = itemService.getPrices(itemIds);
return prices.stream()
.map(priceEntry ->
{
continue;
}
seen.add(itemId);
Item item = new Item();
item.setId(priceEntry.getItem()); // fake item
ItemEntry item = itemService.getItem(itemId);
PriceEntry priceEntry = itemService.getPrice(itemId, null);
if (item == null || priceEntry == null)
{
continue;
}
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()]);
ItemPrice itemPrice = new ItemPrice();
itemPrice.setItem(item);
itemPrice.setPrice(priceEntry.getPrice());
itemPrice.setTime(priceEntry.getTime());
return itemPrice;
})
.toArray(ItemPrice[]::new);
}
}

View File

@@ -30,8 +30,10 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.time.Instant;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentLinkedQueue;
import lombok.extern.slf4j.Slf4j;
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)
{
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")
.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);
if (seen.contains(itemId))
{
continue;
}
seen.add(itemId);
PriceEntry priceEntry = getPrice(con, itemId, null);
if (priceEntry == null)
{
continue;
}
priceEntries.add(priceEntry);
}
return priceEntries;
}
}