哈希映射,类似于有序映射,允许您以键值对的形式存储内存数据。与有序映射不同的是,它们不维护任何排序保证。此数据结构对于需要简单数据缓存和快速访问的情况非常有用,例如共享库存、实体拍卖行等。如果您有超过 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(),并传入键 名称、用于更新的 回调函数 和 过期时间(以秒为单位)。
对于大多数游戏,多个服务器可以同时更新相同的键并更改其值。由于 MemoryStoreHashMap:UpdateAsync() 总是会在更新之前修改最新的值,您应该使用它来读取最新值作为回调函数的输入。
例如,以下代码示例更新共享库存中某资源的数量。MemoryStoreHashMap: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
end
MemoryStoreHashMap:UpdateAsync() 的延迟与 MemoryStoreHashMap:GetAsync() 和 MemoryStoreHashMap: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