W zależności od wpisywaćstruktury danych, MemoryStoreService egzekwuje ograniczenia na pamięci i liczbie pozycji w strukturze danych. Wszystkie struktury danych są również ograniczone przez globalny limit prośby na podzielnik.
Każde doświadczenie Roblox ma Dashboard Obszarów Przechowywania Pamięci, który zawiera zestawy czarpania, które możesz użyć do monitorowania użycia pamięci.
Sortowane Mapy i Kolejki
Sortowane mapy i kolejki mają obie ograniczenia maksymalnej liczby pozycji i maksymalnej pamięci. Ponadto elementy w jednej z tych struktur danych zawsze znajdują się na jednej partycji. Każde zapytanie do jednej z tych struktur danych jest zapytaniem do tej samej partycji.
Gdy sortowany mapa lub kolejka osiągnie swój limit przedmiotu lub pamięci, najlepszym krokiem jest usuwanie niepotrzebnych pozycji ręcznie lub dodawanie polityki wygasania dla pozycji. Alternatywnie, jeśli tylko limit pamięci powoduje zacięcie, można spróbować zmniejszyć rozmiar pozycji poprzez usunięcie niepotrzebnych informacji z kluczy i wartości.
Jeśli potrzebujesz wszystkich swoich przedmiotów lub doświadczasz zacięcia z powodu przepustnicy wniosków, jedynym rozwiązaniem jest podzielenie.
Segregacja
Szyfrowanie to proces przechowywania zestawu powiązanych danych na kilku strukturach danych. Innymi słowy, oznacza to wzięcie istniejącej, wysokoprzepustowej struktury danych i zastąpienie jej mniejszymi, bardziej podatnymi na to, co oryginalne.
Głównym wyzwaniem dla podziału jest znalezienie sposób rozprzestrzeniania danych na wiele struktur danych w taki sposób, aby zachować tę samą funkcjonalność co oryginalny.
Obszukiwanie sortowanej mapy
Aby rozdzielić sortowany mapy, rozważ rozdzielenie swoich danych na alfabetyczne podziały z zasięgami znaków. Na przykład, załóż, że masz tylko klucze z pierwszej litery z A-Z i wierzysz, że cztery sortowane mapy są wystarczające dla twojego obecnego przypadku użycia i przyszłego wzrostu:
- Pierwsza mapa może pokryć A-G, drugie H-N, trzeci O-T i czwarty U-Z.
- Aby wstawić lub odzyskać przedmiot, użyj odpowiedniej mapy w zależności od początkowego postaci przedmiotu.
Obszukiwanie sortowanej mapy
-- Zainicjatyzuj usługę MemoryStore
local MemoryStoreService = game:GetService("MemoryStoreService")
-- Utwórz swoje kosze Sortowane Mapy
local sm_AtoG = MemoryStoreService:GetSortedMap("AtoG")
local sm_HtoM = MemoryStoreService:GetSortedMap("HtoM")
local sm_NtoT = MemoryStoreService:GetSortedMap("NtoT")
local sm_UtoZ = MemoryStoreService:GetSortedMap("UtoZ")
-- Funkcja pomocnicza do odzyskania poprawnego kosza z klucza przedmiotu
local function getSortedMapBucket(itemKey)
if (itemKey >= "a" and itemKey < "h") then
return sm_AtoG
elseif (itemKey < "n") then
return sm_HtoM
elseif (itemKey < "u") then
return sm_NtoT
else
return sm_UtoZ
end
end
-- Z inicjowania imion graczy z domyślną wartością 0
for _, player in game:GetService("Players"):GetPlayers() do
local bucket = getSortedMapBucket(player)
bucket:SetAsync(player, 0, 600)
end
-- Odzyskaj wartość gracza
local player = "myPlayer"
local bucket = getSortedMapBucket(player)
local playerScore = bucket:GetAsync(player)
print(playerScore)
Podzielenie Kolejki
Podzielenie konsoli jest bardziej kłopotliwe niż podzielenie sortowanej mapy. Chociaż chcesz rozprzestrzenić przepustkę poprzez wiele konsoli, dodaje, czytuje i usuwa tylko w przodku lub w tylu konsoli.
Jednym rozwiązaniem jest użycie kręcącej się kolejki, co oznacza tworzenie kilku kolejek i obrót między nimi, gdy dodasz lub przeczytasz przedmiot:
Utwórz kilka kolejek i dodaj ich do matryki.
Utwórz dwa lokalne wskazówki. Jeden przedstawia kolejkę, którą chcesz przeczytać i usunąć przedmioty. Drugi przedstawia kolejkę, którą chcesz dodać przedmioty:
- Dla operacji czytania oblicz liczbę potrzebnych przedmiotów z każdej kolejki, a także gdzie przenieść wskazującym czytaniem.
- Do usuwania operacji przesyłaj ID z czytania do każdej kolejki.
- Dla operacji dodawania, dodaj do kolejki przy użyciu przycisku dodajania i zwiększ przycisk.
Podzielenie Kolejki
-- Zainicjatyzuj usługę MemoryStore
local MemoryStoreService = game:GetService("MemoryStoreService")
-- Utwórz swoje kolejki
local q1 = MemoryStoreService:GetQueue("q1")
local q2 = MemoryStoreService:GetQueue("q2")
local q3 = MemoryStoreService:GetQueue("q3")
local q4 = MemoryStoreService:GetQueue("q4")
-- Umieść kolejki w matrycy
local queueArr = { q1, q2, q3, q4 }
-- Utwórz dwa wskaźniki reprezentujące indeksy czytania i dodaj kolejki
local readIndex = 1
local addIndex = 1
-- Utwórz lokalną funkcję, która aktualizuje indeksy w odpowiedni sposób
local function rotateIndex(index, n)
return (index + n - 1) % 4 + 1
end
-- Utwórz lokalną funkcję, która czyta n pozycji z listy
local function readFromQueue(count, allOrNothing, waitTimeout)
local endIndex = count % 4
local countPerQueue = count // 4
local items = {}
local ids = {}
-- pętla poprzez każdą kolejkę
for i = 1, 4, 1 do
-- określ, czy ta kolejka będzie czytać dodatkowy przedmiot
local diff = i - readIndex
if diff < 0 then
diff += 4
end
local queue = queueArr[i]
-- przeczytaj przedmioty z każdej kolejki
-- +1 pozycji jeśli spełnia dodatkowe kryteria czytania
if diff < endIndex then
items[i], ids[i] = queue:ReadAsync(countPerQueue + 1, allOrNothing,waitTimeout)
else
items[i], ids[i] = queue:ReadAsync(countPerQueue, allOrNothing,waitTimeout)
end
end
readIndex = rotateIndex(readIndex, count)
return items, ids
end
-- Utwórz lokalną funkcję, która usuwa n pozycji z koszyka
local function removeFromQueue(ids)
for i = 1, 4, 1 do
local queue = queueArr[readIndex]
queue:RemoveAsync(ids[i])
end
end
-- Utwórz lokalną funkcję, która dodaje pozycję do kolejki
local function addToQueue(itemKey, expiration, priority)
local queue = queueArr[readIndex]
queue:AddAsync(itemKey, expiration, priority)
addIndex = rotateIndex(addIndex, 1)
end
-- Napisz trochę kodu!
for _, player in game:GetService("Players"):GetPlayers() do
addToQueue(player, 600, 0)
end
local players, ids = readFromQueue(20, true, -1)
removeFromQueue(ids)
Mapy Haszowe
Mapy hash nie mają odrębnych limitów pamięci lub liczby przedmiotów i są automatycznie rozdzielane, ale nadal można je spowolnić, jeśli je źle użyjesz.
Na przykład, rozważaj doświadczenie z mapą haszowania danych gry, przechowywaną jako wartość jednego klucza nazyjącego się metadata. Jeśli ten metadane zawiera zeszyfrowany obiekt z informacjami, takimi jak ID lokacji, liczba graczy i wiele innych, za każdym razem, gdy wymagana jest metoda, możesz mieć wy
Zamiast przechowywania wszystkich metadanych jako jednego, zagnieżdżonego obiektu, lepszym podejściem jest przechowywanie każdego pola jako własnego klucza, aby mapa hachingu mogła skorzystać z automatycznego rozdziału. Jeśli potrzebujesz oddzielenia między metadanymi a resztą mapy hachingu, dodaj naming prefix (tak jak metadata_user_count