Одним из способов было бы использование множеств для представления диапазона дат, где каждый набор представляет один день и идентифицируется целым числом. Члены набора затем представили, какие номера доступны для бронирования в этот день. Поскольку оговорки начинаются и заканчиваются в одно и то же время каждый день, и любая оговорка может быть измерена целыми днями, вы можете представлять любой день как целое число. Например, с помощью эпохи Unix (1 Jan 1970) в качестве времени начала сегодня (24 Апр 2016) будет 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 МБ для резервирования за год.
делать оговорки минимальной фиксированной длины времени? например, любая оговорка должна быть не менее одного дня, начиная и заканчивая в полдень? – aembke
Да, это именно то, как вы это описали. Бронирование - минимум 24 часа, начало/окончание - в полдень. С другой стороны, нет максимальной длины. –