La structure de données carte triée des magasins 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 des clés entrant dans une carte ne détermine pas l'ordre de traitement, ce qui rend les cartes triées utiles pour l'organisation des données de tri pour l'implémentation d'entités dans le jeu pour l'engagement, telles que les tableaux de classement et les enchères inter-serveurs.
Limites
En plus des limites de taille de la 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 avez besoin de stocker des données qui dépassent cette limite pour votre jeu, vous pouvez adopter la technique de sharding pour diviser et distribuer ces données à travers plusieurs structures de données en utilisant un préfixe de clé. Le sharding des magasins mémoire peut également aider à améliorer l'évolutivité 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 au sein du jeu, vous pouvez donc accéder à la même carte triée depuis n'importe quel script en utilisant ce nom.
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")Après avoir obtenu une carte triée, appelez l'une des fonctions suivantes :
| Fonction | Action |
|---|---|
| MemoryStoreSortedMap:SetAsync() | Ajouter une nouvelle clé ou écraser 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 de 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 écraser des données
Pour ajouter une nouvelle clé ou écraser 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 nettoie automatiquement une fois la clé expirée. 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 flottant) 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 par ordre croissant, les clés de tri numériques sont triées en premier, suivies par les clés de tri de chaînes, suivies par les é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 triés uniquement par clé.
Exemple de certaines données triées par 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 est trié après toutes les clés avec une clé de tri. player6 est trié après toutes les clés avec une clé de tri numérique. player4 et player5 ont la même clé de tri, donc elles sont triées par ordre croissant par clé.
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("Set succeeded.")
endObtenir 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 clé de la carte triée, appelez MemoryStoreSortedMap:GetAsync() avec le nom de la clé.
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("Set succeeded.")
end
local item
local getSuccess, getError = pcall(function()
item = sortedMap:GetAsync("User_1234")
end)
if getSuccess then
print(item)
else
warn(getError)
endObtenir 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 toutes les clés existantes par défaut, mais vous pouvez définir les bornes supérieures et inférieures pour la plage de clés. Par exemple, l'exemple de code suivant récupère jusqu'à 20 éléments en commençant par le 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.
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
-- Obtenir jusqu'à 20 éléments en commençant par le 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
endMettre à jour des données
Pour récupérer la valeur et la clé de tri d'une clé d'une carte triée et les 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 de 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 changer la valeur. Comme UpdateAsync() modifie toujours la dernière valeur avant de mettre à jour, vous devriez 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 tableau de classement pour un joueur. Le score est calculé comme tués / morts. UpdateAsync() garantit que les tués et les morts sont mis à jour pour les valeurs les plus récentes même si plusieurs serveurs de jeux mettent à jour le même élément simultanément. Les tués et les morts d'un joueur sont des valeurs monotoniquement croissantes et peuvent donc uniquement augmenter de valeur dans une session.
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
endLa latence pour UpdateAsync() est similaire à GetAsync() et SetAsync() à moins qu'il n'y ait contention.
Lorsque la contention se produit, le système réessaie automatiquement l'opération jusqu'à ce que l'un de ces trois se produise : l'opération réussit, la fonction de rappel renvoie nil, ou le nombre maximum de réessais est atteint. Si le système atteint le nombre maximum de réessais, il renvoie 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 dans une carte triée de magasin mémoire.
Supprimer une clé
Pour supprimer une clé de la carte triée, appelez MemoryStoreSortedMap:RemoveAsync() avec le nom de la clé.
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("Set succeeded.")
end
local removeSuccess, removeError = pcall(function()
sortedMap:RemoveAsync("User_1234")
end)
if not removeSuccess then
warn(removeError)
endSupprimer toutes les données
Pour supprimer la mémoire dans les cartes triées, listez toutes vos clés avec MemoryStoreSortedMap:GetRangeAsync(), puis supprimez-les avec MemoryStoreSortedMap:RemoveAsync().
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
-- La borne inférieure initiale de nil commence le nettoyage à partir du premier élément
local exclusiveLowerBound = nil
while true do
-- Obtenir jusqu'à cent éléments en commençant par la borne 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 avait une erreur lors de la suppression des éléments, réessayez avec la même borne 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 borne inférieure exclusive pour l'itération suivante
exclusiveLowerBound = {}
exclusiveLowerBound["key"] = items[#items].key
exclusiveLowerBound["sortKey"] = items[#items].sortKey
end
end
endObtenir la taille
Pour obtenir le nombre d'éléments dans la carte triée, appelez MemoryStoreSortedMap:GetSizeAsync().
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("Set succeeded.")
end
local size
local success, sizError = pcall(function()
size = sortedMap:GetSizeAsync()
end)
if success then
print(size)
else
warn(sizeError)
end