哈希映射,类似于排序映射,允许您将内存数据存储为键值对。与排序映射不同,哈希映射不维护任何排序保证。这种数据结构对于需要简单数据缓存和快速访问的情况非常有用,例如共享库存、实体拍卖行等。哈希映射会自动处理数据的分区,如果您拥有超过 1,000 个键,这非常有用。对于较小的键空间,我们推荐使用 排序映射。
限制
哈希映射的键大小限制为 128 个字符,值大小限制为 32 KB。
除此之外,哈希映射使用与其他内存存储数据结构相同的 API 请求 和 内存配额 限制。
获取哈希映射
要获取哈希映射,请调用 MemoryStoreService:GetHashMap(),并为哈希映射指定一个名称。该名称在游戏中是全局的,因此您可以在任何脚本中使用该名称访问相同的哈希映射。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("HashMap1")获取哈希映射后,可以调用以下任一函数来读取或写入数据:
| 函数 | 操作 |
|---|---|
| MemoryStoreHashMap:SetAsync() | 添加 新键或如果键已存在,则覆盖值。 |
| MemoryStoreHashMap:GetAsync() | 读取 特定键。 |
| MemoryStoreHashMap:ListItemsAsync() | 列出 哈希映射中的项目。 |
| MemoryStoreHashMap:UpdateAsync() | 更新 从哈希映射中检索到的键的值。 |
| MemoryStoreHashMap:RemoveAsync() | 移除 哈希映射中的键。 |
有关每个函数的详细文档,请参见 MemoryStoreHashMap。
添加或覆盖数据
要添加新键或覆盖哈希映射中键的值,请调用 MemoryStoreHashMap:SetAsync() 并传入键 名称、其 值 以及以秒为单位的 过期时间。一旦键过期,内存会自动清理。最大过期时间为 3,888,000 秒(45 天)。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("HashMap1")
local setSuccess, _ = pcall(function()
return hashMap:SetAsync("User_1234", 1000, 30)
end)
if setSuccess then
print("设置成功。")
end获取数据
您可以获取与特定键关联的值,也可以获取哈希映射中的多个键值对。
获取单一键的数据
要获取与哈希映射中的单一键关联的值,请调用 MemoryStoreHashMap:GetAsync() 并传入键 名称。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("HashMap1")
local setSuccess, _ = pcall(function()
return hashMap:SetAsync("User_1234", 1000, 30)
end)
if setSuccess then
print("设置成功。")
end
local item
local getSuccess, getError = pcall(function()
item = hashMap:GetAsync("User_1234")
end)
if getSuccess then
print(item)
else
warn(getError)
end获取多个键值对的数据
要从哈希映射中一次性获取所有键值对,请调用 MemoryStoreHashMap:ListItemsAsync() 并指定所需的页面大小。此函数以分页的方式列出所有现有的键。例如,以下代码示例从哈希映射中检索最多 32 个项目。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("HashMap1")
-- 每次获取 32 个项目的项目列表
local success, pages = pcall(function()
return hashMap:ListItemsAsync(32)
end)
if success then
while true do
-- 获取当前页面
local entries = pages:GetCurrentPage()
-- 遍历页面上的所有键值对
for _, entry in ipairs(entries) do
print(entry.key .. " : " .. tostring(entry.value))
end
-- 检查是否已到达最后一页
if pages.IsFinished then
break
else
print("----------")
-- 前进到下一页
pages:AdvanceToNextPageAsync()
end
end
end更新数据
要从哈希映射中检索一个键的值并更新它,请调用 MemoryStoreHashMap:UpdateAsync(),并传入键 名称、用于更新键的 回调函数 和以秒为单位的 过期时间。
对于大多数游戏,多个服务器可以同时更新同一键并更改其值。由于 UpdateAsync() 始终在更新之前修改最新值,因此您应该使用它来读取最新值作为回调函数的输入。
例如,以下代码示例更新共享库存中资源的数量。UpdateAsync() 确保所有玩家的贡献都能进入这个共享库存,即使这些贡献是同时做出的。在这个函数中,它还强制最大资源数量为 500。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("ResourceInventory")
local function contributeResources(itemResource, addedCount)
local success, newResourceCount = pcall(function()
return hashMap:UpdateAsync(itemResource, function(resource)
resource = resource or {count = 0}
resource.count = resource.count + addedCount
-- 确保我们不超过最大资源数量
if resource.count > 500 then
resource.count = 500
end
return resource
end, 1200)
end)
if success then
print(newResourceCount)
end
endUpdateAsync() 的延迟与 GetAsync() 和 SetAsync() 类似,除非发生冲突。
当发生冲突时,系统会自动重试操作,直到以下三个情况之一发生:操作成功、回调函数返回 nil 或达到最大重试次数。如果系统达到最大重试次数,它将返回冲突。
移除数据
您可以使用 MemoryStoreHashMap:RemoveAsync() 来移除哈希映射中的一个键,或删除内存存储哈希映射中的所有数据。
移除一个键
要从哈希映射中移除一个键,请调用 MemoryStoreHashMap:RemoveAsync() 并传入键 名称。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("HashMap1")
local setSuccess, _ = pcall(function()
return hashMap:SetAsync("User_1234", 1000, 30)
end)
if setSuccess then
print("设置成功。")
end
local removeSuccess, removeError = pcall(function()
hashMap:RemoveAsync("User_1234")
end)
if not removeSuccess then
warn(removeError)
end删除所有数据
要删除哈希映射中的所有数据,请使用 MemoryStoreHashMap:ListItemsAsync() 列出您的所有项目,然后使用 MemoryStoreHashMap:RemoveAsync() 将它们移除。
local MemoryStoreService = game:GetService("MemoryStoreService")
local hashMap = MemoryStoreService:GetHashMap("HashMap1")
-- 每次获取 32 个项目的项目列表
local success, pages = pcall(function()
return hashMap:ListItemsAsync(32)
end)
if success then
while true do
-- 获取当前页面
local entries = pages:GetCurrentPage()
local removeSuccess = true
local removeError = nil
-- 遍历页面上的所有键值对
for _, entry in ipairs(entries) do
print(entry.key .. " : " .. tostring(entry.value))
removeSuccess, removeError = pcall(function()
hashMap:RemoveAsync(entry.key)
end)
if not removeSuccess then
warn(removeError)
end
end
-- 检查是否已到达最后一页
if pages.IsFinished then
print("完成删除所有数据。")
break
else
print("----------")
-- 前进到下一页
pages:AdvanceToNextPageAsync()
end
end
end