Struktura danych posortowanej mapy w pamięciach umożliwia przechowywanie często używanych danych w pamięci jako par klucz-wartość z opcjonalnym kluczem sortującym i utrzymywanie określonej kolejności na podstawie kluczy sortujących oraz kluczy. W przeciwieństwie do kolejek, kolejność, w jakiej klucze trafiają do mapy, nie określa kolejności przetwarzania, co sprawia, że posortowane mapy są przydatne do organizacji danych pod kątem sortowania w celu implementacji elementów in-game, takich jak rankingi i aukcje międzyserwerowe.
Limity
Oprócz limitów rozmiaru struktury danych, posortowane mapy mają limit długości klucza wynoszący 128 znaków, limit długości wartości wynoszący 32 KB oraz limit długości klucza sortującego wynoszący 128 znaków.
Jeśli musisz przechowywać dane, które przekraczają ten limit w swojej grze, możesz zastosować technikę rozdzielania (shardingu), aby podzielić je i rozdzielić przez prefiks klucza na wiele struktur danych. Sharding pamięci może również pomóc poprawić skalowalność Twojego systemu.
Uzyskaj posortowaną mapę
Aby uzyskać posortowaną mapę, wywołaj MemoryStoreService:GetSortedMap() z nazwą, którą chcesz zdefiniować dla mapy. Nazwa jest globalna w obrębie gry, więc możesz uzyskać dostęp do tej samej posortowanej mapy w każdym skrypcie, używając tej samej nazwy.
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")Po uzyskaniu posortowanej mapy, możesz wywołać dowolną z poniższych funkcji:
| Funkcja | Akcja |
|---|---|
| MemoryStoreSortedMap:SetAsync() | Dodaj nowy klucz lub nadpisz wartość i/lub klucz sortujący, jeśli klucz już istnieje. |
| MemoryStoreSortedMap:GetAsync() | Odczytaj konkretny klucz. |
| MemoryStoreSortedMap:GetRangeAsync() | Odczytaj wszystkie istniejące klucze lub konkretny zakres z nich. |
| MemoryStoreSortedMap:UpdateAsync() | Aktualizuj wartość klucza i/lub klucz sortujący po odzyskaniu go z posortowanej mapy. |
| MemoryStoreSortedMap:RemoveAsync() | Usuń klucz z posortowanej mapy. |
| MemoryStoreSortedMap:GetSizeAsync() | Uzyskaj liczbę elementów w posortowanej mapie. |
Dodaj lub nadpisz dane
Aby dodać nowy klucz lub nadpisać wartość lub klucz sortujący klucza w posortowanej mapie, wywołaj MemoryStoreSortedMap:SetAsync() z nazwą klucza, jego wartością, czasem wygaśnięcia w sekundach oraz opcjonalnym kluczem sortującym. Pamięć automatycznie sprzątana jest po wygaśnięciu klucza. Maksymalny czas wygaśnięcia wynosi 3 888 000 sekund (45 dni). Klucz sortujący, jeśli jest podany, musi być prawidłową liczbą (całkowitą lub zmiennoprzecinkową) lub ciągiem.
W kolejności sortowania Twoich kluczy klucz sortujący ma pierwszeństwo przed kluczem. Na przykład, przy sortowaniu rosnącym, numeryczne klucze sortujące sortują się jako pierwsze, a następnie ciągowe klucze sortujące, a następnie elementy bez klucza sortującego. Wszystkie elementy z numerycznymi kluczami sortującymi są sortowane według klucza sortującego, jeśli klucz sortujący dla dwóch elementów jest równy, są one sortowane według klucza. Podobnie, wszystkie elementy z ciągłymi kluczami sortującymi są sortowane według klucza sortującego, jeśli klucz sortujący dla dwóch elementów jest równy, są one sortowane według klucza. Wszystkie elementy bez klucza sortującego są sortowane tylko według klucza.
Przykład danych posortowanych w kolejności rosnącej -
{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}Zauważ, jak player0 sortuje się po wszystkich kluczach z kluczem sortującym. player6 sortuje się po wszystkich kluczach z numerycznym kluczem sortującym. player4 i player5 mają ten sam klucz sortujący, więc są sortowani rosnąco według klucza.
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("Dodawanie powiodło się.")
endUzyskaj dane
Możesz uzyskać wartość danych i klucz sortujący powiązany z konkretnym kluczem lub uzyskać wiele wartości i kluczy sortujących dla kluczy w zakresie.
Uzyskaj dane z jednym kluczem
Aby uzyskać wartość i klucz sortujący powiązany z jednym kluczem z posortowanej mapy, wywołaj MemoryStoreSortedMap:GetAsync() z nazwą klucza.
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("Dodawanie powiodło się.")
end
local item
local getSuccess, getError = pcall(function()
item = sortedMap:GetAsync("User_1234")
end)
if getSuccess then
print(item)
else
warn(getError)
endUzyskaj dane z wieloma kluczami
Aby uzyskać dane dla wielu kluczy z posortowanej mapy jako jedną operację, wywołaj MemoryStoreSortedMap:GetRangeAsync(). Ta funkcja domyślnie wypisuje wszystkie istniejące klucze, ale możesz ustawić górne i dolne granice dla zakresu kluczy. Na przykład poniższy przykład kodu pobiera do 20 elementów, zaczynając od początku posortowanej mapy, z kluczami większymi lub równymi 10, kluczami sortującymi większymi lub równymi 100 oraz kluczami mniejszymi lub równymi 50, kluczami sortującymi mniejszymi lub równymi 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
-- Uzyskaj do 20 elementów zaczynając od początku
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
endZaktualizuj dane
Aby uzyskać wartość i klucz sortujący klucza z posortowanej mapy i je zaktualizować, wywołaj MemoryStoreSortedMap:UpdateAsync() z nazwą klucza, funkcją zwrotną do aktualizacji wartości i klucza sortującego dla tego klucza oraz czasem wygaśnięcia w sekundach. Maksymalny czas wygaśnięcia wynosi 3 888 000 sekund (45 dni).
W większości gier wiele serwerów może jednocześnie zaktualizować ten sam klucz i zmienić wartość. Ponieważ UpdateAsync() zawsze modyfikuje ostatnią wartość przed aktualizacją, powinieneś go użyć do odczytania ostatniej wartości jako wejścia dla swojej funkcji zwrotnej.
Na przykład, poniższy przykład kodu aktualizuje wynik w rankingu dla gracza. Wynik jest obliczany jako zabójstwa / zgony. UpdateAsync() zapewnia, że zabójstwa i zgony są aktualizowane dla najnowszych wartości, nawet jeśli wiele serwerów gier aktualizuje ten sam element jednocześnie. Zabójstwa i zgony gracza są wartościami monotonicznie rosnącymi, więc mogą tylko wzrastać w wartościach w sesji.
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` to klucz sortujący używany do sortowania elementów w mapie
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
endOpóźnienie dla UpdateAsync() jest podobne do GetAsync() i SetAsync(), chyba że wystąpi konflikt.
Gdy wystąpi konflikt, system automatycznie powtarza operację, aż jedno z tych trzech wydarzy się: operacja się powiedzie, funkcja zwrotna zwraca nil, lub osiągnięto maksymalną liczbę prób. Jeśli system osiągnie maksymalną liczbę prób, zwraca konflikt.
Usuń dane
Możesz użyć MemoryStoreSortedMap:RemoveAsync() zarówno do usunięcia jednego klucza z posortowanej mapy, jak i do usunięcia wszystkich danych w posortowanej mapie pamięci.
Usuń klucz
Aby usunąć klucz z posortowanej mapy, wywołaj MemoryStoreSortedMap:RemoveAsync() z nazwą klucza.
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("Dodawanie powiodło się.")
end
local removeSuccess, removeError = pcall(function()
sortedMap:RemoveAsync("User_1234")
end)
if not removeSuccess then
warn(removeError)
endUsuń wszystkie dane
Aby usunąć pamięć w posortowanych mapach, wypisz wszystkie swoje klucze za pomocą MemoryStoreSortedMap:GetRangeAsync(), a następnie usuń je za pomocą MemoryStoreSortedMap:RemoveAsync().
local MemoryStoreService = game:GetService("MemoryStoreService")
local sortedMap = MemoryStoreService:GetSortedMap("SortedMap1")
-- Początkowa granica dolna równająca się nil rozpoczyna czyszczenie od pierwszego elementu
local exclusiveLowerBound = nil
while true do
-- Uzyskaj do stu elementów, zaczynając od aktualnej dolnej granicy
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
-- Jeśli wystąpił błąd przy usuwaniu elementów, spróbuj ponownie z tą samą ekskluzywną dolną granicą
if not removeSuccess then
warn(removeError)
-- Jeśli zakres jest mniejszy od stu elementów, osiągnięto koniec mapy
elseif #items < 100 then
break
else
-- Ostatnio pobrany klucz jest ekskluzywną dolną granicą dla następnej iteracji
exclusiveLowerBound = {}
exclusiveLowerBound["key"] = items[#items].key
exclusiveLowerBound["sortKey"] = items[#items].sortKey
end
end
endUzyskaj rozmiar
Aby uzyskać liczbę elementów w posortowanej mapie, wywołaj 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("Dodawanie powiodło się.")
end
local size
local success, sizError = pcall(function()
size = sortedMap:GetSizeAsync()
end)
if success then
print(size)
else
warn(sizeError)
end