各位帮忙讨论讨论这个有什么高效的实现方式

2016-08-07 22:40:58 +08:00
 hao123yinlong

场景

有 N 个 球 ( 百万个 )放在仓库 ,每次会有 M 个 (< 10 个) 同学会逐个进入操场中 ,这时候需要从仓库中取出球来给这些同学们玩 ( 每个同学完成各自指定量的球后,自动退场) , 每个球会给在场的同学们传递一遍(如果传球过程中,其中一个同学 之前传过这个球,就跳过这个同学,直接传给下一个同学),然后扔掉 ,并且记录下每个同学传过哪些球 。

需求

从仓库取球时 ,需要计算后,优先取出所有在场同学都没有玩过的球 ; 如果不存在在场同学都没玩过的球,则尽量取出没被在场同学玩过的球

待完善方案

Redis 存储

当 id 为 1 同学进场时 ,在 Redis 中,执行

SDIFFSTORE all_stu_can_play_balls all_ball stu:id1

all_stu_can_play_balls 为 key 的 SET 用来存储在场同学都能玩的球集合

当 id 为 m 的同学进场时 ,在 Redis 中,执行

SDIFFSTORE all_stu_can_play_balls all_ball stu:idm:balls

key 为 all_stu_can_play_balls 更新为 最新的能被所有在场同学试玩的球 id 的 SET

当 id 为 m 的同学传递一次球后, 在 Redis 中 ZADD 一次

当 id 为 m 的同学完成其指定的传递次数后,退场时 ,挨个用 all_balls 对在场同学的 stu:idm:balls 执行 SDIFFSTORE ,重新计算 all_stu_can_play_balls 。

即 完成了取出能被所有在场同学玩的球 ,但是如果 all_stu_can_play_balls 被所有同学都试玩了后,如何取到 尽量多能被在场同学玩的球呢?

Now

上面这个不完整方案只是抛砖引玉,还请各位 v2er 完善或者提出更优完整的方案

2024 次点击
所在节点    酷工作
2 条回复
hao123yinlong
2016-08-07 22:52:27 +08:00
抱歉 ,编辑出错 ,应该是

# 当 id 为 m 的同学进场时 ,在 Redis 中,执行
<br/>
SDIFFSTORE all_stu_can_play_balls all_stu_can_play_balls stu:idm:balls
<br/>
key 为 all_stu_can_play_balls 更新为 最新的能被所有在场同学试玩的球 id 的 SET
Joan114
2016-08-25 10:01:34 +08:00
体育游戏?球 id 作为 key 放 redis , value 为已经传过该球的同学的 id ,每次把拿出来的球的 value 和当前在场的同学 id 比较一下,如果全部已经传过(看你们需求是重新获取一个球,还是这个球在场滚一圈下去,哈哈。。。),另外一种情况就是场上的同学包含没有传过该球的,那么按照你们需求(随机获取场景同学 id 进行传,或者场景同学的顺序传,巴拉巴拉。。。。),每当球经过一个同学的时候,记录一下 id ,这里有个优化点是,不用每当球发生变化就去及时更新 redis , redis 是单线程操作的,如果房间(就是你这里说的场景)开多了,就会出现性能问题,可以把 memory 利用起来啊,定时或者场景传递完毕后再往 redis 里面 flush


巴拉巴拉的一大堆,不知道是不是你们想要的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/297749

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX