A estrutura de dados mapa classificado dos armazenamentos em memória permite armazenar dados frequentes em memória como pares chave-valor com uma chave de ordenação opcional e manter uma ordem específica com base nas chaves de ordenação e chaves. Ao contrário das filas, a ordem das chaves que entram em um mapa não determina a ordem de processamento, tornando os mapas classificados úteis para organizar dados baseados em classificação para implementar entidades no jogo para engajamento, como placares e leilões entre servidores.
Limites
Além dos limites de tamanho da estrutura de dados, os mapas classificados têm um limite de tamanho de chave de 128 caracteres, um limite de tamanho de valor de 32 KB e um limite de tamanho de chave de ordenação de 128 caracteres.
Se você precisar armazenar dados que superem esse limite para seu jogo, pode adotar a técnica de fragmentação para dividir e distribuir por meio de prefixo de chave em várias estruturas de dados. A fragmentação de armazéns de memória também pode ajudar a melhorar a escalabilidade do seu sistema.
Obter um mapa classificado
Para obter um mapa classificado, chame MemoryStoreService:GetSortedMap() com um nome que você deseja definir para o mapa. O nome é global dentro do jogo, então você pode acessar o mesmo mapa classificado em qualquer script usando o nome.
Obtendo um Mapa Classificadolocal MemoryStoreService = game:GetService("MemoryStoreService")local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
Depois de obter um mapa classificado, chame qualquer uma das seguintes funções:
| Função | Ação |
|---|---|
| MemoryStoreSortedMap:SetAsync() | Adicionar uma nova chave ou sobrescrever o valor e/ou chave de ordenação se a chave já existir. |
| MemoryStoreSortedMap:GetAsync() | Ler uma chave específica. |
| MemoryStoreSortedMap:GetRangeAsync() | Ler todas as chaves existentes ou um intervalo específico delas. |
| MemoryStoreSortedMap:UpdateAsync() | Atualizar o valor de uma chave e/ou chave de ordenação após recuperá-la de um mapa classificado. |
| MemoryStoreSortedMap:RemoveAsync() | Remover uma chave do mapa classificado. |
| MemoryStoreSortedMap:GetSizeAsync() | Obter o número de itens no mapa classificado. |
Adicionar ou sobrescrever dados
Para adicionar uma nova chave ou sobrescrever o valor ou chave de ordenação de uma chave no mapa classificado, chame MemoryStoreSortedMap:SetAsync() com o nome da chave, seu valor, um tempo de expiração em segundos e uma chave de ordenação opcional. A memória é limpa automaticamente uma vez que a chave expira. O tempo máximo de expiração é de 3.888.000 segundos (45 dias). A chave de ordenação, se fornecida, deve ser um número válido (inteiro ou ponto flutuante) ou uma string.
Na ordem de classificação de suas chaves, uma chave de ordenação tem precedência sobre uma chave. Por exemplo, ao ordenar em ordem crescente, chaves de ordenação numérica são classificadas primeiro, seguidas por chaves de ordenação de string, seguidas por itens sem chave de ordenação. Todos os itens com chaves de ordenação numéricas são ordenados pela chave de ordenação; se a chave de ordenação para dois itens for igual, eles são ordenados pela chave. Da mesma forma, todos os itens com chaves de ordenação de string são ordenados pela chave de ordenação; se a chave de ordenação para dois itens for igual, eles são ordenados pela chave. Todos os itens sem chave de ordenação são classificados apenas pela chave.
Exemplo de alguns dados ordenados em ordem crescente -
{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}
Note como player0 é classificado após todas as chaves com uma chave de ordenação. player6 é classificado após todas as chaves com uma chave de ordenação numérica. player4 e player5 têm a mesma chave de ordenação, portanto, são classificados em ordem crescente pela chave.
Adicionando Dados a um Mapa Classificado
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
Obter dados
Você pode obter um valor e chave de ordenação associados a uma chave específica ou obter múltiplos valores e chaves de ordenação para chaves dentro de um intervalo.
Obter dados com uma chave
Para obter um valor e chave de ordenação associados a uma chave do mapa classificado, chame MemoryStoreSortedMap:GetAsync() com o nome da chave.
Obtendo uma Chave Particular de um Mapa Classificado
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)
end
Obter dados com múltiplas chaves
Para obter dados de múltiplas chaves do mapa classificado como uma única operação, chame MemoryStoreSortedMap:GetRangeAsync(). Esta função lista todas as chaves existentes por padrão, mas você pode definir os limites superior e inferior para o intervalo de chaves. Por exemplo, o seguinte exemplo de código recupera até 20 itens começando do início do mapa classificado, com chaves maiores ou iguais a 10, chaves de ordenação maiores ou iguais a 100 e chaves menores ou iguais a 50, chaves de ordenação menores ou iguais a 500.
Obtendo um Intervalo de Chaves de um Mapa Classificado
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
-- Obtenha até 20 itens começando do início
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
Atualizar dados
Para recuperar o valor e a chave de ordenação de uma chave de um mapa classificado e atualizá-lo, chame MemoryStoreSortedMap:UpdateAsync() com o nome da chave, uma função de callback para atualizar o valor e a chave de ordenação dessa chave e um tempo de expiração em segundos. O tempo máximo de expiração é de 3.888.000 segundos (45 dias).
Para a maioria dos jogos, múltiplos servidores podem atualizar a mesma chave simultaneamente e alterar o valor. Como UpdateAsync() sempre modifica o último valor antes de atualizar, você deve usá-lo para ler o último valor como entrada para sua função de callback.
Por exemplo, o seguinte exemplo de código atualiza a pontuação em um placar para um jogador. A pontuação é calculada como mortes / mortes. UpdateAsync() garante que as mortes e os assassinatos sejam atualizados para os valores mais recentes, mesmo se múltiplos servidores de jogo atualizarem o mesmo item simultaneamente. As mortes e as mortes de um jogador são valores que aumentam monotonamente e, portanto, só podem aumentar em valor em uma sessão.
Atualizando a pontuação do placar para um jogador em um Mapa Classificado
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` é a chave de ordenação sendo usada para classificar itens no mapa
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
A latência para UpdateAsync() é semelhante a GetAsync() e SetAsync() a menos que haja contenção.
Quando a contenção ocorre, o sistema automaticamente retria a operação até que um destes três ocorra: a operação seja bem-sucedida, a função de callback retorne nil, ou o número máximo de tentativas seja atingido. Se o sistema atingir o número máximo de tentativas, ele retorna um conflito.
Remover dados
Você pode usar MemoryStoreSortedMap:RemoveAsync() tanto para remover uma chave do mapa classificado quanto para deletar todos os dados em um mapa classificado de armazenamento de memória.
Remover uma chave
Para remover uma chave do mapa classificado, chame MemoryStoreSortedMap:RemoveAsync() com o nome da chave.
Remover uma Chave de um Mapa Classificado
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)
end
Deletar todos os dados
Para deletar a memória em mapas classificados, liste todas as suas chaves com MemoryStoreSortedMap:GetRangeAsync(), e então remova-as com MemoryStoreSortedMap:RemoveAsync().
Deletar Memória em um Mapa Classificado
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
-- O limite inferior inicial de nil inicia a limpeza a partir do primeiro item
local exclusiveLowerBound = nil
while true do
-- Obtenha até cem itens começando do limite inferior atual
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
-- Se houve um erro ao remover itens, tente novamente com o mesmo limite inferior exclusivo
if not removeSuccess then
warn(removeError)
-- Se o intervalo for menor que cem itens, o final do mapa foi alcançado
elseif #items < 100 then
break
else
-- A última chave recuperada é o limite inferior exclusivo para a próxima iteração
exclusiveLowerBound = {}
exclusiveLowerBound["key"] = items[#items].key
exclusiveLowerBound["sortKey"] = items[#items].sortKey
end
end
end
Obter o tamanho
Para obter o número de itens no mapa classificado, chame MemoryStoreSortedMap:GetSizeAsync().
Obtendo o Tamanho de um Mapa Classificado
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