From ca44d30a5b146d414f672eaff8d4803513eceafe Mon Sep 17 00:00:00 2001 From: Yang Chun Ung Date: Fri, 14 Jun 2024 11:42:43 +0900 Subject: [PATCH] Use cached sheet --- .../ArenaParticipantsWorkerTest.cs | 9 +++++- .../MemoryCacheExtensionsTest.cs | 22 +++++++++++++++ .../ArenaParticipantsWorker.cs | 28 +++++++++++++------ .../MemoryCacheExtensions.cs | 28 +++++++++++++++++++ 4 files changed, 78 insertions(+), 9 deletions(-) diff --git a/NineChronicles.Headless.Tests/ArenaParticipantsWorkerTest.cs b/NineChronicles.Headless.Tests/ArenaParticipantsWorkerTest.cs index 887b59f4f..232dcabfa 100644 --- a/NineChronicles.Headless.Tests/ArenaParticipantsWorkerTest.cs +++ b/NineChronicles.Headless.Tests/ArenaParticipantsWorkerTest.cs @@ -5,6 +5,8 @@ using Libplanet.Action.State; using Libplanet.Crypto; using Libplanet.Mocks; +using Microsoft.Extensions.Caching.Memory; +using Microsoft.Extensions.Options; using Nekoyume; using Nekoyume.Action; using Nekoyume.Model.Arena; @@ -13,6 +15,7 @@ using Nekoyume.Model.State; using Nekoyume.Module; using Nekoyume.TableData; +using Nekoyume.TableData.Rune; using Xunit; using Random = Libplanet.Extensions.ActionEvaluatorCommonComponents.Random; @@ -183,7 +186,11 @@ public void GetArenaParticipants() state = state.SetLegacyState(Addresses.GetSheetAddress(key), s.Serialize()); } var avatarAddrAndScoresWithRank = ArenaParticipantsWorker.AvatarAddrAndScoresWithRank(participants.AvatarAddresses, currentRoundData, state); - var actual = ArenaParticipantsWorker.GetArenaParticipants(state, participants.AvatarAddresses, avatarAddrAndScoresWithRank); + var cache = new MemoryCache(new OptionsWrapper(new MemoryCacheOptions + { + SizeLimit = null + })); + var actual = ArenaParticipantsWorker.GetArenaParticipants(state, participants.AvatarAddresses, avatarAddrAndScoresWithRank, cache.GetSheet(state), cache.GetSheet(state), cache.GetSheet(state), cache.GetSheet(state)); Assert.Equal(2, actual.Count); var first = actual.First(); Assert.Equal(avatarAddress, first.AvatarAddr); diff --git a/NineChronicles.Headless.Tests/MemoryCacheExtensionsTest.cs b/NineChronicles.Headless.Tests/MemoryCacheExtensionsTest.cs index d5d016d7e..30f2324e1 100644 --- a/NineChronicles.Headless.Tests/MemoryCacheExtensionsTest.cs +++ b/NineChronicles.Headless.Tests/MemoryCacheExtensionsTest.cs @@ -2,10 +2,13 @@ using System.Threading.Tasks; using Bencodex; using Bencodex.Types; +using Libplanet.Action.State; +using Libplanet.Mocks; using MessagePack; using Microsoft.Extensions.Caching.Memory; using Microsoft.Extensions.Options; using Nekoyume; +using Nekoyume.Module; using Nekoyume.TableData; using Xunit; @@ -36,4 +39,23 @@ public async Task Sheet() await Task.Delay(100); Assert.False(cache.TryGetValue(cacheKey, out byte[] _)); } + + [Fact] + public void GetSheet_With_Type() + { + var cache = new MemoryCache(new OptionsWrapper(new MemoryCacheOptions + { + SizeLimit = null + })); + + var sheets = TableSheetsImporter.ImportSheets(); + var tableName = nameof(ItemRequirementSheet); + var csv = sheets[tableName]; + var sheetAddress = Addresses.GetSheetAddress(tableName); + var value = (Text)csv; + var state = (IWorld) new World(MockWorldState.CreateModern()); + state = state.SetLegacyState(sheetAddress, value); + var cachedSheet = cache.GetSheet(state); + Assert.Equal(value, cachedSheet.Serialize()); + } } diff --git a/NineChronicles.Headless/ArenaParticipantsWorker.cs b/NineChronicles.Headless/ArenaParticipantsWorker.cs index c31d7f792..669dbfac1 100644 --- a/NineChronicles.Headless/ArenaParticipantsWorker.cs +++ b/NineChronicles.Headless/ArenaParticipantsWorker.cs @@ -193,14 +193,21 @@ public static ArenaSheet.RoundData GetRoundData(IWorldState worldState, long blo /// The world state from which to retrieve the arena participants. /// The list of avatar addresses to filter the matching participants. /// The list of avatar addresses with their scores and ranks. + /// + /// + /// + /// /// A list of arena participants. - public static List GetArenaParticipants(IWorldState worldState, List
avatarAddrList, List<(Address avatarAddr, int score, int rank)> avatarAddrAndScoresWithRank) + public static List GetArenaParticipants( + IWorldState worldState, + List
avatarAddrList, + List<(Address avatarAddr, int score, int rank)> avatarAddrAndScoresWithRank, + RuneListSheet runeListSheet, + CostumeStatSheet costumeStatSheet, + CharacterSheet characterSheet, + RuneOptionSheet runeOptionSheet + ) { - var runeListSheet = worldState.GetSheet(); - var costumeSheet = worldState.GetSheet(); - var characterSheet = worldState.GetSheet(); - var runeOptionSheet = worldState.GetSheet(); - var runeIds = runeListSheet.Values.Select(x => x.Id).ToList(); var row = characterSheet[GameConfig.DefaultAvatarCharacterId]; CollectionSheet collectionSheet = new CollectionSheet(); var collectionStates = worldState.GetCollectionStates(avatarAddrList); @@ -265,7 +272,7 @@ List runeSlotList } } - var cp = CPHelper.TotalCP(equipments, costumes, runeOptions, avatar.level, row, costumeSheet, collectionModifiers, + var cp = CPHelper.TotalCP(equipments, costumes, runeOptions, avatar.level, row, costumeStatSheet, collectionModifiers, RuneHelper.CalculateRuneLevelBonus(runeStates, runeListSheet, worldState.GetSheet()) ); var portraitId = StateQuery.GetPortraitId(equipments, costumes); @@ -315,7 +322,12 @@ public void PrepareArenaParticipants() var avatarAddrList = participants.AvatarAddresses; var avatarAddrAndScoresWithRank = AvatarAddrAndScoresWithRank(avatarAddrList, currentRoundData, worldState); - var result = GetArenaParticipants(worldState, avatarAddrList, avatarAddrAndScoresWithRank); + var sheetCache = _cache.SheetCache; + var runeListSheet = sheetCache.GetSheet(worldState); + var costumeStatSheet = sheetCache.GetSheet(worldState); + var characterSheet = sheetCache.GetSheet(worldState); + var runeOptionSheet = sheetCache.GetSheet(worldState); + var result = GetArenaParticipants(worldState, avatarAddrList, avatarAddrAndScoresWithRank, runeListSheet, costumeStatSheet, characterSheet, runeOptionSheet); _cache.ArenaParticipantsCache.Set(cacheKey, result, TimeSpan.FromHours(1)); sw.Stop(); _logger.Information("[ArenaParticipantsWorker]Set Arena Cache[{CacheKey}]: {Elapsed}", cacheKey, sw.Elapsed); diff --git a/NineChronicles.Headless/MemoryCacheExtensions.cs b/NineChronicles.Headless/MemoryCacheExtensions.cs index 3cda79d22..169241e57 100644 --- a/NineChronicles.Headless/MemoryCacheExtensions.cs +++ b/NineChronicles.Headless/MemoryCacheExtensions.cs @@ -1,8 +1,12 @@ using System; using Bencodex; using Bencodex.Types; +using Libplanet.Action.State; using MessagePack; using Microsoft.Extensions.Caching.Memory; +using Nekoyume; +using Nekoyume.Module; +using Nekoyume.TableData; namespace NineChronicles.Headless; @@ -32,4 +36,28 @@ public static bool TryGetSheet(this MemoryCache cache, string cacheKey, out T return null; } + + public static T GetSheet(this MemoryCache cache, IWorldState worldState) where T : ISheet, new() + { + var cacheKey = Addresses.GetSheetAddress().ToString(); + var sheet = new T(); + var csv = string.Empty; + if (cache.GetSheet(cacheKey) is { } s) + { + csv = s; + } + else + { + IValue value = Null.Value; + if (worldState.GetSheetCsv() is { } s2) + { + csv = s2; + value = (Text)csv; + } + cache.SetSheet(cacheKey, value, TimeSpan.FromMinutes(1)); + } + + sheet.Set(csv); + return sheet; + } }