Compare commits

...

1 Commits

Author SHA1 Message Date
Michael Green
308338580d Cache objects from database in memory to improve performance (#151)
* IGDB objects are now cached in memory

* Completed caching of PlatformMaps
2023-10-10 23:59:52 +11:00
2 changed files with 111 additions and 17 deletions

View File

@@ -4,6 +4,7 @@ using System.Reflection;
using gaseous_tools; using gaseous_tools;
using IGDB; using IGDB;
using IGDB.Models; using IGDB.Models;
using Microsoft.Extensions.Caching.Memory;
namespace gaseous_server.Classes.Metadata namespace gaseous_server.Classes.Metadata
{ {
@@ -16,14 +17,32 @@ namespace gaseous_server.Classes.Metadata
Expired Expired
} }
private static Dictionary<string, MemoryCacheObject> ObjectCache = new Dictionary<string, MemoryCacheObject>();
public static CacheStatus GetCacheStatus(string Endpoint, string Slug) public static CacheStatus GetCacheStatus(string Endpoint, string Slug)
{ {
return _GetCacheStatus(Endpoint, "slug", Slug); CacheClean();
if (ObjectCache.ContainsKey(Endpoint + Slug))
{
return CacheStatus.Current;
}
else
{
return _GetCacheStatus(Endpoint, "slug", Slug);
}
} }
public static CacheStatus GetCacheStatus(string Endpoint, long Id) public static CacheStatus GetCacheStatus(string Endpoint, long Id)
{ {
return _GetCacheStatus(Endpoint, "id", Id); CacheClean();
if (ObjectCache.ContainsKey(Endpoint + Id))
{
return CacheStatus.Current;
}
else
{
return _GetCacheStatus(Endpoint, "id", Id);
}
} }
public static CacheStatus GetCacheStatus(DataRow Row) public static CacheStatus GetCacheStatus(DataRow Row)
@@ -164,6 +183,21 @@ namespace gaseous_server.Classes.Metadata
{ {
string Endpoint = EndpointType.GetType().Name; string Endpoint = EndpointType.GetType().Name;
if (ObjectCache.ContainsKey(Endpoint + SearchValue))
{
MemoryCacheObject cacheObject = ObjectCache[Endpoint + SearchValue];
if (cacheObject.ExpiryTime < DateTime.UtcNow)
{
// object has expired, remove it
ObjectCache.Remove(Endpoint + SearchValue);
}
else
{
// object is valid, return it
return (T)cacheObject.Object;
}
}
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
string sql = "SELECT * FROM " + Endpoint + " WHERE " + SearchField + " = @" + SearchField; string sql = "SELECT * FROM " + Endpoint + " WHERE " + SearchField + " = @" + SearchField;
@@ -181,7 +215,11 @@ namespace gaseous_server.Classes.Metadata
else else
{ {
DataRow dataRow = dt.Rows[0]; DataRow dataRow = dt.Rows[0];
return BuildCacheObject<T>(EndpointType, dataRow); object returnObject = BuildCacheObject<T>(EndpointType, dataRow);
ObjectCache.Add(Endpoint + SearchValue, new MemoryCacheObject{
Object = returnObject
});
return (T)returnObject;
} }
} }
@@ -380,6 +418,31 @@ namespace gaseous_server.Classes.Metadata
return EndpointType; return EndpointType;
} }
private static void CacheClean()
{
Dictionary<string, MemoryCacheObject> workCache = ObjectCache;
foreach (KeyValuePair<string, MemoryCacheObject> objectCache in workCache)
{
if (objectCache.Value.ExpiryTime < DateTime.UtcNow)
{
ObjectCache.Remove(objectCache.Key);
}
}
}
private class MemoryCacheObject
{
public object Object { get; set; }
public DateTime CreationTime { get; } = DateTime.UtcNow;
public DateTime ExpiryTime
{
get
{
return CreationTime.AddMinutes(60);
}
}
}
} }
} }

View File

@@ -15,6 +15,8 @@ namespace gaseous_server.Models
{ {
public class PlatformMapping public class PlatformMapping
{ {
private static Dictionary<string, PlatformMapItem> PlatformMapCache = new Dictionary<string, PlatformMapItem>();
/// <summary> /// <summary>
/// Updates the platform map from the embedded platform map resource /// Updates the platform map from the embedded platform map resource
/// </summary> /// </summary>
@@ -98,7 +100,15 @@ namespace gaseous_server.Models
List<PlatformMapItem> platformMaps = new List<PlatformMapItem>(); List<PlatformMapItem> platformMaps = new List<PlatformMapItem>();
foreach (DataRow row in data.Rows) foreach (DataRow row in data.Rows)
{ {
platformMaps.Add(BuildPlatformMapItem(row)); long mapId = (long)row["Id"];
if (PlatformMapCache.ContainsKey(mapId.ToString()))
{
platformMaps.Add(PlatformMapCache[mapId.ToString()]);
}
else
{
platformMaps.Add(BuildPlatformMapItem(row));
}
} }
platformMaps.Sort((x, y) => x.IGDBName.CompareTo(y.IGDBName)); platformMaps.Sort((x, y) => x.IGDBName.CompareTo(y.IGDBName));
@@ -109,23 +119,30 @@ namespace gaseous_server.Models
public static PlatformMapItem GetPlatformMap(long Id) public static PlatformMapItem GetPlatformMap(long Id)
{ {
Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString); if (PlatformMapCache.ContainsKey(Id.ToString()))
string sql = "SELECT * FROM PlatformMap WHERE Id = @Id";
Dictionary<string, object> dbDict = new Dictionary<string, object>();
dbDict.Add("Id", Id);
DataTable data = db.ExecuteCMD(sql, dbDict);
if (data.Rows.Count > 0)
{ {
PlatformMapItem platformMap = BuildPlatformMapItem(data.Rows[0]); return PlatformMapCache[Id.ToString()];
return platformMap;
} }
else else
{ {
Exception exception = new Exception("Platform Map Id " + Id + " does not exist."); Database db = new gaseous_tools.Database(Database.databaseType.MySql, Config.DatabaseConfiguration.ConnectionString);
Logging.Log(Logging.LogType.Critical, "Platform Map", "Platform Map Id " + Id + " does not exist.", exception); string sql = "SELECT * FROM PlatformMap WHERE Id = @Id";
throw exception; Dictionary<string, object> dbDict = new Dictionary<string, object>();
dbDict.Add("Id", Id);
DataTable data = db.ExecuteCMD(sql, dbDict);
if (data.Rows.Count > 0)
{
PlatformMapItem platformMap = BuildPlatformMapItem(data.Rows[0]);
return platformMap;
}
else
{
Exception exception = new Exception("Platform Map Id " + Id + " does not exist.");
Logging.Log(Logging.LogType.Critical, "Platform Map", "Platform Map Id " + Id + " does not exist.", exception);
throw exception;
}
} }
} }
@@ -218,6 +235,11 @@ namespace gaseous_server.Models
db.ExecuteCMD(sql, dbDict); db.ExecuteCMD(sql, dbDict);
} }
} }
if (PlatformMapCache.ContainsKey(item.IGDBId.ToString()))
{
PlatformMapCache.Remove(item.IGDBId.ToString());
}
} }
static PlatformMapItem BuildPlatformMapItem(DataRow row) static PlatformMapItem BuildPlatformMapItem(DataRow row)
@@ -321,6 +343,15 @@ namespace gaseous_server.Models
}; };
mapItem.Bios = bioss; mapItem.Bios = bioss;
if (PlatformMapCache.ContainsKey(IGDBId.ToString()))
{
PlatformMapCache[IGDBId.ToString()] = mapItem;
}
else
{
PlatformMapCache.Add(IGDBId.ToString(), mapItem);
}
return mapItem; return mapItem;
} }