一种方法是使用集合来表示日期范围,其中每个集合代表一天并由整数标识。然后,一组成员将代表当天哪些房间可供预订。由于预订每天在同一时间开始和结束,并且任何预订都可以用一整天来衡量,因此您可以将任何一天表示为整数。例如,使用 Unix 纪元(1970 年 1 月 1 日)作为开始时间,今天(2016 年 4 月 24 日)将是 16915。或者在 JavaScript 中:
Math.floor(new Date().getTime() / (1000 * 60 * 60 * 24));
然后,您可以通过在输入范围内的天数上进行设置交集来查找在给定日期范围内哪些房间可用。 This gives you O(n * m) lookup time 其中n 是最小集合的大小,m 是集合的数量。由于该集合最多包含每个房间一次,这意味着n 受房间总数的限制。例如:
var _ = require("lodash");
var dateToInt = function(date){
return Math.floor(date.getTime() / (1000 * 60 * 60 * 24));
};
var roomsInRange = function(client, start, end, callback){
client.sinter(_.range(dateToInt(start), dateToInt(end)), callback);
};
当用户为某个日期范围预订房间时,您会从该日期范围内的每个集合中删除该房间号。
var _ = require("lodash");
var dateToInt = function(date){
return Math.floor(date.getTime() / (1000 * 60 * 60 * 24));
};
var reserveRoom = function(client, start, end, room, callback){
var trx = client.multi();
_.each(_.range(dateToInt(start), dateToInt(end), function(day){
trx.srem(day, room);
});
trx.exec(callback);
};
这种方法复制了大量数据,因为每个房间都被多次表示,但大小受房间数量和您需要表示的最大日期范围的限制。例如,我认为不允许用户提前 5 年进行预订,也不允许他们在过去进行预订,这意味着除了限制输入范围的上限之外,您还可以清理过去的条目。鉴于键是整数,并且房间也可能用整数表示,如果一年的预订需要超过 1 或 2 MB 的空间,我会感到惊讶。