La structure de données carte triée des magasins en mémoire vous permet de stocker des données fréquentes en mémoire sous forme de paires clé-valeur avec une clé de tri optionnelle et de maintenir un ordre spécifique basé sur les clés de tri et les clés. Contrairement aux files d'attente, l'ordre d'entrée des clés dans une carte ne détermine pas l'ordre de traitement, ce qui rend les cartes triées utiles pour l'organisation basée sur le tri des données pour la mise en œuvre d'entités de jeu pour l'engagement, telles que les classements et les enchères inter-serveurs.
Limites
En plus des limitations de taille de structure de données, les cartes triées ont une limite de taille de clé de 128 caractères, une limite de taille de valeur de 32 Ko, et une limite de taille de clé de tri de 128 caractères.
Si vous devez stocker des données dépassant cette limite pour votre jeu, vous pouvez adopter la technique du sharding pour les diviser et les distribuer par préfixe de clé dans plusieurs structures de données. Le sharding des magasins en mémoire peut également aider à améliorer la scalabilité de votre système.
Obtenir une carte triée
Pour obtenir une carte triée, appelez MemoryStoreService:GetSortedMap() avec un nom que vous souhaitez définir pour la carte. Le nom est global dans le jeu, donc vous pouvez accéder à la même carte triée dans n'importe quel script en utilisant le nom.
Obtention d'une carte triéelocal MemoryStoreService = game:GetService("MemoryStoreService")local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
Après avoir obtenu une carte triée, vous pouvez appeler l'une des fonctions suivantes :
| Fonction | Action |
|---|---|
| MemoryStoreSortedMap:SetAsync() | Ajouter une nouvelle clé ou remplacer la valeur et/ou la clé de tri si la clé existe déjà. |
| MemoryStoreSortedMap:GetAsync() | Lire une clé particulière. |
| MemoryStoreSortedMap:GetRangeAsync() | Lire toutes les clés existantes ou une plage spécifique d'entre elles. |
| MemoryStoreSortedMap:UpdateAsync() | Mettre à jour la valeur d'une clé et/ou la clé de tri après l'avoir récupérée d'une carte triée. |
| MemoryStoreSortedMap:RemoveAsync() | Supprimer une clé de la carte triée. |
| MemoryStoreSortedMap:GetSizeAsync() | Obtenir le nombre d'éléments dans la carte triée. |
Ajouter ou remplacer des données
Pour ajouter une nouvelle clé ou remplacer la valeur ou la clé de tri d'une clé dans la carte triée, appelez MemoryStoreSortedMap:SetAsync() avec le nom de la clé, sa valeur, un temps d'expiration en secondes et une clé de tri optionnelle. La mémoire se nettoie automatiquement une fois que la clé expire. Le temps d'expiration maximum est de 3 888 000 secondes (45 jours). La clé de tri, si fournie, doit être un nombre valide (entier ou à virgule flottante) ou une chaîne.
Dans l'ordre de tri de vos clés, une clé de tri a la priorité sur une clé. Par exemple, lors du tri dans l'ordre croissant, les clés de tri numériques sont triées en premier, suivies des clés de tri de chaînes, puis des éléments sans clé de tri. Tous les éléments avec des clés de tri numériques sont triés par clé de tri, si la clé de tri de deux éléments est égale, ils sont triés par clé. De même, tous les éléments avec des clés de tri de chaînes sont triés par clé de tri, si la clé de tri de deux éléments est égale, ils sont triés par clé. Tous les éléments sans clé de tri sont simplement triés par la clé.
Exemple de certaines données triées dans l'ordre croissant -
{key: "player1", value: someValue1, sortKey: -1}{key: "player2", value: someValue2, sortKey: 0}{key: "player4", value: someValue3, sortKey: 1}{key: "player5", value: someValue4, sortKey: 1}{key: "player3", value: someValue5, sortKey: 3.14}{key: "player6", value: someValue6, sortKey: "someString"}{key: "player0", value: someValue7}{key: "player7", value: someValue8}
Notez comment player0 se range après toutes les clés avec une clé de tri. player6 se range après toutes les clés avec une clé de tri numérique. player4 et player5 ont la même clé de tri, elles sont donc triées par ordre croissant par clé.
Ajout de données à une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, 3.14152)
end)
if setSuccess then
print("L'ajout a réussi.")
end
Obtenir des données
Vous pouvez soit obtenir une valeur de données et une clé de tri associée à une clé spécifique, soit obtenir plusieurs valeurs et clés de tri pour des clés dans une plage.
Obtenir des données avec une clé
Pour obtenir une valeur et une clé de tri associées à une seule clé de la carte triée, appelez MemoryStoreSortedMap:GetAsync() avec le nom de la clé.
Obtenir une clé particulière d'une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, 3.14152)
end)
if setSuccess then
print("L'ajout a réussi.")
end
local item
local getSuccess, getError = pcall(function()
item = sortedMap:GetAsync("User_1234")
end)
if getSuccess then
print(item)
else
warn(getError)
end
Obtenir des données avec plusieurs clés
Pour obtenir des données pour plusieurs clés de la carte triée en une seule opération, appelez MemoryStoreSortedMap:GetRangeAsync(). Cette fonction liste par défaut toutes les clés existantes, mais vous pouvez définir les limites supérieure et inférieure pour la plage de clés. Par exemple, l'exemple de code suivant récupère jusqu'à 20 éléments à partir du début de la carte triée, avec des clés supérieures ou égales à 10, des clés de tri supérieures ou égales à 100 et des clés inférieures ou égales à 50, des clés de tri inférieures ou égales à 500.
Obtention d'une plage de clés d'une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local lowerBound = {}
lowerBound["key"] = "10"
lowerBound["sortKey"] = 100
local upperBound = {}
upperBound["key"] = "50"
upperBound["sortKey"] = 500
-- Obtenez jusqu'à 20 éléments à partir du début
local getSuccess, items = pcall(function()
return sortedMap:GetRangeAsync(
Enum.SortDirection.Ascending, 20, lowerBound, upperBound)
end)
if getSuccess then
for _, item in items do
print(item.key)
print(item.sortKey)
end
end
Mettre à jour les données
Pour récupérer la valeur et la clé de tri d'une clé dans une carte triée et la mettre à jour, appelez MemoryStoreSortedMap:UpdateAsync() avec le nom de la clé, une fonction de rappel pour mettre à jour la valeur et la clé de tri pour cette clé, et un temps d'expiration en secondes. Le temps d'expiration maximum est de 3 888 000 secondes (45 jours).
Pour la plupart des jeux, plusieurs serveurs peuvent mettre à jour la même clé simultanément et modifier la valeur. Comme UpdateAsync() modifie toujours la dernière valeur avant de mettre à jour, vous devez l'utiliser pour lire la dernière valeur comme entrée pour votre fonction de rappel.
Par exemple, l'exemple de code suivant met à jour le score dans un classement pour un joueur. Le score est calculé comme le ratio des kills / des deaths. UpdateAsync() garantit que les kills et les deaths sont mis à jour avec les valeurs les plus récentes, même si plusieurs serveurs de jeu mettent à jour le même élément simultanément. Les kills et les deaths d'un joueur sont des valeurs croissantes et ne peuvent donc qu'augmenter en valeur dans une session.
Mise à jour du score du classement pour un joueur dans une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("Leaderboard")
local function updateLeaderboard(itemKey, killsToAdd, deathsToAdd)
local success, newStats, newScore = pcall(function()
return sortedMap:UpdateAsync(itemKey, function(playerStats, playerScore)
playerStats = playerStats or { kills = 0, deaths = 0 }
playerStats.kills += killsToAdd
playerStats.deaths += deathsToAdd
if playerStats then
-- `playerScore` est la clé de tri utilisée pour trier les éléments dans la carte
playerScore = playerStats.kills / math.max(playerStats.deaths, 1)
return playerStats, playerScore
end
return nil
end, 30)
end)
if success then
print(newStats)
print(newScore)
end
end
La latence pour UpdateAsync() est similaire à celle de GetAsync() et SetAsync() sauf en cas de contention.
Lorsque la contention se produit, le système réessaie automatiquement l'opération jusqu'à ce que l'une de ces trois choses se produise : l'opération réussit, la fonction de rappel renvoie nil, ou le nombre maximum de tentatives est atteint. Si le système atteint le nombre maximum de tentatives, il retourne un conflit.
Supprimer des données
Vous pouvez utiliser MemoryStoreSortedMap:RemoveAsync() pour à la fois supprimer une clé de la carte triée et supprimer toutes les données d'une carte triée en mémoire.
Supprimer une clé
Pour supprimer une clé de la carte triée, appelez MemoryStoreSortedMap:RemoveAsync() avec le nom de la clé.
Supprimer une clé d'une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, "someStringSortKey")
end)
if setSuccess then
print("L'ajout a réussi.")
end
local removeSuccess, removeError = pcall(function()
sortedMap:RemoveAsync("User_1234")
end)
if not removeSuccess then
warn(removeError)
end
Supprimer toutes les données
Pour supprimer la mémoire dans les cartes triées, répertoriez toutes vos clés avec MemoryStoreSortedMap:GetRangeAsync(), puis supprimez-les avec MemoryStoreSortedMap:RemoveAsync().
Supprimer la mémoire dans une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
-- Limite inférieure initiale de nil commence à vider depuis le premier élément
local exclusiveLowerBound = nil
while true do
-- Obtenez jusqu'à cent éléments à partir de la limite inférieure actuelle
local getRangeSuccess, items = pcall(function()
return sortedMap:GetRangeAsync(Enum.SortDirection.Ascending, 100, exclusiveLowerBound)
end)
if getRangeSuccess then
local removeSuccess = true
local removeError = nil
for _, item in items do
removeSuccess, removeError = pcall(function()
sortedMap:RemoveAsync(item.key)
end)
end
-- S'il y a eu une erreur en supprimant des éléments, essayez à nouveau avec la même limite inférieure exclusive
if not removeSuccess then
warn(removeError)
-- Si la plage est inférieure à cent éléments, la fin de la carte est atteinte
elseif #items < 100 then
break
else
-- La dernière clé récupérée est la limite inférieure exclusive pour la prochaine itération
exclusiveLowerBound = {}
exclusiveLowerBound["key"] = items[#items].key
exclusiveLowerBound["sortKey"] = items[#items].sortKey
end
end
end
Obtenir la taille
Pour obtenir le nombre d'éléments dans la carte triée, appelez MemoryStoreSortedMap:GetSizeAsync().
Obtenir la taille d'une carte triée
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
local setSuccess, _ = pcall(function()
return sortedMap:SetAsync("User_1234", 1000, 30, 3.14152)
end)
if setSuccess then
print("L'ajout a réussi.")
end
local size
local success, sizeError = pcall(function()
size = sortedMap:GetSizeAsync()
end)
if success then
print(size)
else
warn(sizeError)
end