I'm building a website. It has groups that users can join.
The difference between this and "normal" groups is that membership is temporary - when a user joins a group, he decides the length of membership: 5 days, a week, 2 weeks, etc (choices are pre-defined). Or potentially all memberships could be set to be of the same length - say a week - if that makes thing simpler.
I'd like to have a running tally of the number of members of each group. The number doesn't need to be accurate up to the last second. But it can't be too out of date either - say, should be updated once a day.
The "obvious" way to calculate the number of members seems to be running a cron job, say daily, and go through every member of every group one by one. If a membership has expired, remove that member from the group and decrement the group's membership count by 1.
That approach seems very inefficient and not very scalable. With a large number of groups, it could take forever.
Can you think of a better way to do this? The membership counts do not need to be accurate to the latest second. It can be approximate and (slightly) out of date. Also if it makes a 开发者_JAVA技巧difference all memberships can be set to be of the same length, say a week.
Store a list of how many people are currently in each group. Also store a list of days. Each day will contain a list of groups, and how many people to subtract from that group on that day.
When a person joins a group, add 1 to the group total, and add 1 to the people-to-subtract for that group on the day his/her membership will expire.
If a person's expiration-date changes, remove 1 from the people-to-subtract from the old expiration-date (for that group), and add 1 to the new expiration-date.
Finally, of course, once a day subtract the correct amount from each group for that day.
If all memberships are the same length, simply maintain a FIFO of memberships due to expire. Every time you get a new member, add an 'expires' entry to the end of the list, with the date set 1 week later.
Now, as often as you like, check the front of the list for expiring memberships, and update the count of the group. Stop when you get to the first entry which hasn't expired yet.
This could also work for variable length memberships, but you'd have to maintain a sorted list.
When a member joins, you know when their membership will expire. So, instead of searching for a list of members to deactivate daily (or however often), you can add each member to the appropriate list of memberships that expire on the same day. Then, every day you just go through and delete the expired memberships for that day. It's pretty much what you said, except that instead of searching, you store the results.
The size of your storage is proportional to the length of your longest membership.
精彩评论