There are multiple meeting rooms
I did came with the below design. Do let me know any shortcoming of this. Tried running this locally to handler concurrent cases and it was working fine.
@AllArgsConstructor
@Getter
public class User {
String name;
String email;
}
@AllArgsConstructor
@Getter
@Builder
public class Meetings {
String id;
long startTime;
long endTime;
List<User> invitees;
}
@AllArgsConstructor
@Getter
@Builder
public class MeetingRoom {
int id;
int capacity;
Calender calender;
MailClient mailClient;
public boolean checkAvailability(Interval interval) {
return calender.checkAvailability(interval);
}
public Meetings bookMeetingRoom(Interval interval, List<User> users) {
Meetings meetings = Meetings.builder()
.id(UUID.randomUUID().toString())
.startTime(interval.getStartTime())
.endTime(interval.getEndTime())
.invitees(users)
.build();
calender.addMeeting(meetings);
for (User user : users) {
mailClient.sendMail(user.getEmail());
}
return meetings;
}
}
@AllArgsConstructor
@Getter
@Builder
public class Calender {
List<Meetings> meetingsList;
TreeMap<Long, Long> calendar;
boolean checkAvailability(Interval interval) {
for (Meetings meeting : meetingsList) {
long startTime = meeting.getStartTime();
long endTime = meeting.getEndTime();
calendar.put(startTime, endTime);
}
Integer prev = Math.toIntExact(calendar.floorKey(interval.getStartTime())),
next = Math.toIntExact(calendar.ceilingKey(interval.getStartTime()));
if ((prev == null || calendar.get(prev) <= interval.getStartTime()) &&
(next == null || interval.getEndTime() <= next)) {
return true;
}
return false;
}
void addMeeting(Meetings meeting) {
calendar.put(meeting.getStartTime(), meeting.getEndTime());
meetingsList.add(meeting);
}
}
@AllArgsConstructor
@Data
@Slf4j
public class MeetingRoomScheduler {
List<MeetingRoom> meetingRoomList;
synchronized Meetings bookMeetingRoom(Interval interval, List<User> users) {
for (MeetingRoom meetingRoom : meetingRoomList) {
if (users.size() == meetingRoom.getCapacity()) {
if (meetingRoom.checkAvailability(interval)) {
Meetings meetingDetails = meetingRoom.bookMeetingRoom(interval, users);
log.info("Booked meeting in room {} with details {}", meetingRoom.getId(), meetingDetails);
return meetingDetails;
}
}
}
log.info("No meeting room found as of now for your time");
return null;
}
}
@AllArgsConstructor
@Getter
@Builder
@Slf4j
public class MailClient {
public void sendMail(String email) {
log.info("Sending mail to this id {}", email);
}
}
@AllArgsConstructor
@Getter
@Builder
public class Interval {
long startTime;
long endTime;
}