There are multiple meeting rooms

  • Meeting room can be allocated at any time in a day. There is no contraint on the time.
  • Meeting room can be occupied for any time duration. Example for 30 mins or may be for 2 hours as well.
  • Proper error message should be given incase meeting room can't be booked for given time slots.
  • Send notification to person invited in meeting room
  • Use calender invite to track date and time of meeting room

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;
}
Comments (4)