会员专享
请先
登录,登录后可使用今日免费解锁;
开通会员,或
购买
该题目所属题库
,可解锁完整内容。
解题思路
本题是带懒过期的分片互斥租约模拟。维护两张表:
lease[shard] = (clientId, expireAt)
by_client[clientId] = {shard: expireAt}
每次读写前,用当前 now 清理相关分片/客户端上已过期的租约(now≥expireAt 即失效)。
题目内容
分布式存储把数据空间划成 shardCount 个分片(编号 0∼shardCount−1)。客户端通过租约互斥持有分片:同一时刻每个分片最多被一个客户端持有;每个客户端同时持有的未过期租约数不能超过 maxHold。
时间用整数时刻表示。租约采用懒过期:只有在某次调用传入的 now 上判断时,若 now≥expireAt 则视为已过期并释放占用,不主动扫表。
请实现类 ShardLeaseManager:
-
ShardLeaseManager(int shardCount, int maxHold):初始化。shardCount、maxHold 均为正整数。构造输出 null。
-
bool acquire(int clientId, int shardId, int now, int ttl):客户端 clientId 尝试在时刻 now 租用分片 shardId,租期长度为 ttl(过期时刻为 now+ttl,即 now+ttl 起失效)。
- 若 clientId≤0 或 ttl≤0 或 shardId 越界,返回 false
- 先按 now 清理该分片及该客户端名下已过期租约
- 若该分片仍被其他客户端持有,返回 false
- 若该分片已被同一客户端持有且未过期,视为续租失败通道外的重复申请,返回 false(应走 renew)
- 若清理后该客户端持有数已达 maxHold,返回 false
- 否则写入租约并返回 true
-
bool renew(int clientId, int shardId, int now, int ttl):仅当 clientId 当前仍持有该未过期租约时,把过期时刻更新为 now+ttl;ttl≤0 或参数非法返回 false
-
bool release(int clientId, int shardId, int now):仅持有者可释放;先按 now 判断是否仍持有,成功清除后返回 true,否则 false
-
int owner(int shardId, int now):返回当前未过期持有者的 clientId;空闲或越界返回 −1
-
int heldCount(int clientId, int now):返回该客户端当前未过期租约数;clientId≤0 返回 −1
约束:累计调用 ≤8000;1≤shardCount≤1000;1≤maxHold≤shardCount;1≤clientId≤106;0≤now≤109;1≤ttl≤109(非法参数由对应接口返回失败)。
输入描述
每行一次函数调用,首行必为 ShardLeaseManager(shardCount, maxHold)。
输出描述
每次调用一行:
- 构造输出 null
- acquire / renew / release 输出 true / false
- owner / heldCount 输出整数
样例1
输入:
ShardLeaseManager(3, 2)
acquire(1, 0, 0, 10)
acquire(1, 1, 1, 10)
acquire(1, 2, 2, 10)
owner(0, 5)
heldCount(1, 5)
acquire(2, 0, 5, 5)
release(1, 0, 5)
acquire(2, 0, 5, 5)
renew(1, 1, 8, 10)
owner(1, 8)
owner(1, 20)
输出:
null
true
true
false
1
2
false
true
true
true
1
-1
说明:
- 客户端 1 最多持有 2 个分片,第三次 acquire 失败
- 分片 0 被 1 占用时,2 无法抢占;1 释放后 2 可租用
- renew 把分片 1 的过期时刻延到 18;时刻 20 查询已过期
样例2
输入:
ShardLeaseManager(2, 1)
acquire(0, 0, 0, 1)
acquire(1, 0, 0, 5)
acquire(1, 0, 0, 5)
renew(1, 0, 3, 2)
release(1, 0, 4)
release(1, 0, 4)
owner(0, 4)
heldCount(1, 4)
输出:
null
false
true
false
true
true
false
-1
0
说明:clientId 必须为正;同一客户端对已持有分片再次 acquire 返回 false;释放后不能再释放。