From 832a5b116ba800b9914d1712dd4e4fcc25d93ca1 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Mon, 8 May 2023 22:56:37 +0200 Subject: [PATCH] Update memory store to use concurrent dictionary Fixes #3741 --- .../Elsa.Common/Services/MemoryStore.cs | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/modules/Elsa.Common/Services/MemoryStore.cs b/src/modules/Elsa.Common/Services/MemoryStore.cs index cf644eea4..e261352fe 100644 --- a/src/modules/Elsa.Common/Services/MemoryStore.cs +++ b/src/modules/Elsa.Common/Services/MemoryStore.cs @@ -1,21 +1,56 @@ +using System.Collections.Concurrent; using Elsa.Common.Entities; namespace Elsa.Common.Services; +/// +/// A simple in-memory store for entities. +/// +/// The type of entity to store. public class MemoryStore { - private IDictionary Entities { get; set; } = new Dictionary(); + private IDictionary Entities { get; set; } = new ConcurrentDictionary(); + + /// + /// Adds or updates an entity. + /// + /// The entity to add or update. + /// A function that returns the ID of the entity. public void Save(TEntity entity, Func idAccessor) => Entities[idAccessor(entity)] = entity; + /// + /// Adds or updates many entities. + /// + /// The entities to add or update. + /// A function that returns the ID of the entity. public void SaveMany(IEnumerable entities, Func idAccessor) { foreach (var entity in entities) Save(entity, idAccessor); } + /// + /// Finds an entity matching the specified predicate. + /// + /// A predicate to match. + /// The matching entity or null if no match was found. public TEntity? Find(Func predicate) => Entities.Values.Where(predicate).FirstOrDefault(); + + /// + /// Finds all entities matching the specified predicate. + /// + /// A predicate to match. + /// The matching entities. public IEnumerable FindMany(Func predicate) => Entities.Values.Where(predicate); + /// + /// Finds all entities matching the specified predicate and orders them by the specified key. + /// + /// The predicate to match. + /// The key to order by. + /// The order direction. + /// The type of the key. + /// The matching entities. public IEnumerable FindMany(Func predicate, Func orderBy, OrderDirection orderDirection = OrderDirection.Ascending) { var query = Entities.Values.Where(predicate); @@ -30,10 +65,24 @@ public class MemoryStore return query; } + /// + /// Lists all entities. + /// + /// All entities. public IEnumerable List() => Entities.Values; + /// + /// Deletes an entity by ID. + /// + /// The ID of the entity to delete. + /// True if the entity was deleted, otherwise false. public bool Delete(string id) => Entities.Remove(id); + /// + /// Deletes all entities matching the specified predicate. + /// + /// The predicate to match. + /// The number of entities deleted. public int DeleteWhere(Func predicate) { var query = @@ -48,6 +97,11 @@ public class MemoryStore return entries.Count; } + /// + /// Deletes all entities matching the specified IDs. + /// + /// The IDs of the entities to delete. + /// The number of entities deleted. public int DeleteMany(IEnumerable ids) { var count = 0; @@ -60,6 +114,12 @@ public class MemoryStore return count; } + /// + /// Deletes the specified entities. + /// + /// The entities to delete. + /// A function that returns the ID of the entity. + /// public int DeleteMany(IEnumerable entities, Func idAccessor) { var count = 0; @@ -75,11 +135,21 @@ public class MemoryStore return count; } + /// + /// Returns a queryable of all entities. + /// + /// A function that returns a queryable. + /// A queryable of all entities. public IEnumerable Query(Func, IQueryable> query) { var queryable = Entities.Values.AsQueryable(); return query(queryable); } + /// + /// Returns true if any entity matches the specified predicate. + /// + /// The predicate to match. + /// True if any entity matches the specified predicate, otherwise false. public bool AnyAsync(Func predicate) => Entities.Values.Any(predicate); } \ No newline at end of file