diff --git a/src/Client/Client.cs b/src/Client/Client.cs index b4df755..290681d 100644 --- a/src/Client/Client.cs +++ b/src/Client/Client.cs @@ -121,13 +121,13 @@ public class Client }), new StringContent(settings, Encoding.UTF8, "application/json")); } - public async Task SearchdomainGetQueriesAsync(string searchdomain) + public async Task SearchdomainGetQueriesAsync(string searchdomain) { Dictionary parameters = new() { {"searchdomain", searchdomain} }; - return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Searchdomain", "Queries", parameters)); + return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Searchdomain", "Queries", parameters)); } public async Task SearchdomainQueryAsync(string query) @@ -190,13 +190,13 @@ public class Client return await FetchUrlAndProcessJson(HttpMethod.Put, GetUrl($"{baseUri}/Searchdomain", "Settings", parameters), content); } - public async Task SearchdomainGetQueryCacheSizeAsync(string searchdomain) + public async Task SearchdomainGetQueryCacheSizeAsync(string searchdomain) { Dictionary parameters = new() { {"searchdomain", searchdomain} }; - return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Searchdomain/QueryCache", "Size", parameters)); + return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Searchdomain/QueryCache", "Size", parameters)); } public async Task SearchdomainClearQueryCache(string searchdomain) @@ -222,9 +222,9 @@ public class Client return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Server", "Models", [])); } - public async Task ServerGetEmbeddingCacheSizeAsync() + public async Task ServerGetStatsAsync() { - return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Server/EmbeddingCache", "Size", [])); + return await FetchUrlAndProcessJson(HttpMethod.Get, GetUrl($"{baseUri}/Server/Stats", "Size", [])); } private async Task FetchUrlAndProcessJson(HttpMethod httpMethod, string url, HttpContent? content = null) diff --git a/src/Server/Controllers/SearchdomainController.cs b/src/Server/Controllers/SearchdomainController.cs index 2eca1c2..e0caab6 100644 --- a/src/Server/Controllers/SearchdomainController.cs +++ b/src/Server/Controllers/SearchdomainController.cs @@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; using Server.Exceptions; using Server.Helper; +using Shared; using Shared.Models; namespace Server.Controllers; @@ -134,13 +135,13 @@ public class SearchdomainController : ControllerBase /// /// Name of the searchdomain [HttpGet("Queries")] - public ActionResult GetQueries([Required]string searchdomain) + public ActionResult GetQueries([Required]string searchdomain) { (Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger); if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message}); - Dictionary searchCache = searchdomain_.searchCache; + Dictionary searchCache = searchdomain_.queryCache.AsDictionary(); - return Ok(new SearchdomainSearchesResults() { Searches = searchCache, Success = true }); + return Ok(new SearchdomainQueriesResults() { Searches = searchCache, Success = true }); } /// @@ -175,7 +176,7 @@ public class SearchdomainController : ControllerBase { (Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger); if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message}); - Dictionary searchCache = searchdomain_.searchCache; + EnumerableLruCache searchCache = searchdomain_.queryCache; bool containsKey = searchCache.ContainsKey(query); if (containsKey) { @@ -196,7 +197,7 @@ public class SearchdomainController : ControllerBase { (Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger); if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message}); - Dictionary searchCache = searchdomain_.searchCache; + EnumerableLruCache searchCache = searchdomain_.queryCache; bool containsKey = searchCache.ContainsKey(query); if (containsKey) { @@ -237,6 +238,7 @@ public class SearchdomainController : ControllerBase }; searchdomain_.helper.ExecuteSQLNonQuery("UPDATE searchdomain set settings = @settings WHERE id = @id", parameters); searchdomain_.settings = request; + searchdomain_.queryCache.Capacity = request.QueryCacheSize; return Ok(new SearchdomainUpdateResults(){Success = true}); } @@ -245,15 +247,17 @@ public class SearchdomainController : ControllerBase /// /// Name of the searchdomain [HttpGet("QueryCache/Size")] - public ActionResult GetSearchCacheSize([Required]string searchdomain) + public ActionResult GetQueryCacheSize([Required]string searchdomain) { if (!SearchdomainHelper.IsSearchdomainLoaded(_domainManager, searchdomain)) { - return Ok(new SearchdomainSearchCacheSizeResults() { QueryCacheSizeBytes = 0, Success = true }); + return Ok(new SearchdomainQueryCacheSizeResults() { SizeBytes = 0, ElementCount = 0, ElementMaxCount = 0, Success = true }); } (Searchdomain? searchdomain_, int? httpStatusCode, string? message) = SearchdomainHelper.TryGetSearchdomain(_domainManager, searchdomain, _logger); if (searchdomain_ is null || httpStatusCode is not null) return StatusCode(httpStatusCode ?? 500, new SearchdomainUpdateResults(){Success = false, Message = message}); - return Ok(new SearchdomainSearchCacheSizeResults() { QueryCacheSizeBytes = searchdomain_.GetSearchCacheSize(), Success = true }); + int elementCount = searchdomain_.queryCache.Count(); + int ElementMaxCount = searchdomain_.settings.QueryCacheSize; + return Ok(new SearchdomainQueryCacheSizeResults() { SizeBytes = searchdomain_.GetSearchCacheSize(), ElementCount = elementCount, ElementMaxCount = ElementMaxCount, Success = true }); } /// diff --git a/src/Server/Searchdomain.cs b/src/Server/Searchdomain.cs index c5a1971..ce5cc12 100644 --- a/src/Server/Searchdomain.cs +++ b/src/Server/Searchdomain.cs @@ -4,6 +4,7 @@ using System.Text.Json; using ElmahCore.Mvc.Logger; using MySql.Data.MySqlClient; using Server.Helper; +using Shared; using Shared.Models; using AdaptiveExpressions; @@ -17,7 +18,7 @@ public class Searchdomain public string searchdomain; public int id; public SearchdomainSettings settings; - public Dictionary searchCache; // Key: query, Value: Search results for that query (with timestamp) + public EnumerableLruCache queryCache; // Key: query, Value: Search results for that query (with timestamp) public List entityCache; public List modelsInUse; public LRUCache> embeddingCache; @@ -33,12 +34,12 @@ public class Searchdomain this.aIProvider = aIProvider; this.embeddingCache = embeddingCache; this._logger = logger; - searchCache = []; entityCache = []; connection = new MySqlConnection(connectionString); connection.Open(); helper = new SQLHelper(connection, connectionString); settings = GetSettings(); + queryCache = new(settings.QueryCacheSize); modelsInUse = []; // To make the compiler shut up - it is set in UpdateSearchDomain() don't worry // yeah, about that... if (!runEmpty) { @@ -163,7 +164,7 @@ public class Searchdomain public List<(float, string)> Search(string query, int? topN = null) { - if (searchCache.TryGetValue(query, out DateTimedSearchResult cachedResult)) + if (queryCache.TryGetValue(query, out DateTimedSearchResult cachedResult)) { cachedResult.AccessDateTimes.Add(DateTime.Now); return [.. cachedResult.Results.Select(r => (r.Score, r.Name))]; @@ -187,7 +188,7 @@ public class Searchdomain [.. sortedResults.Select(r => new ResultItem(r.Item1, r.Item2 ))] ); - searchCache[query] = new DateTimedSearchResult(DateTime.Now, searchResult); + queryCache.Set(query, new DateTimedSearchResult(DateTime.Now, searchResult)); return results; } @@ -292,7 +293,7 @@ public class Searchdomain { if (settings.CacheReconciliation) { - foreach (KeyValuePair element in searchCache) + foreach (var element in queryCache) { string query = element.Key; DateTimedSearchResult searchResult = element.Value; @@ -322,7 +323,7 @@ public class Searchdomain { if (settings.CacheReconciliation) { - foreach (KeyValuePair element in searchCache) + foreach (KeyValuePair element in queryCache) { string query = element.Key; DateTimedSearchResult searchResult = element.Value; @@ -337,13 +338,13 @@ public class Searchdomain public void InvalidateSearchCache() { - searchCache = []; + queryCache = new(settings.QueryCacheSize); } public long GetSearchCacheSize() { long sizeInBytes = 0; - foreach (var entry in searchCache) + foreach (var entry in queryCache) { sizeInBytes += sizeof(int); // string length prefix sizeInBytes += entry.Key.Length * sizeof(char); // string characters diff --git a/src/Server/Views/Home/Searchdomains.cshtml b/src/Server/Views/Home/Searchdomains.cshtml index 5dbbe77..f482afe 100644 --- a/src/Server/Views/Home/Searchdomains.cshtml +++ b/src/Server/Views/Home/Searchdomains.cshtml @@ -62,11 +62,17 @@

@T["Settings"]

+
+ + +
-
+
+
+
@@ -347,10 +353,20 @@