Beispiel #1
0
        /// <summary>
        /// New client arrives
        /// </summary>
        /// <param name="groupSize">Group size</param>
        /// <returns>Returns new registered group</returns>
        public ClientsGroup Arrive(int groupSize)
        {
            if (Table.MaxSize < groupSize)
            {
                throw new RestaurantException($"Sorry, but we have only tables with {Table.MaxSize} places");
            }

            var newGroup = new ClientsGroup(groupSize, Guid.NewGuid());

            this.restManager.OnArrive(newGroup);
            return(newGroup);
        }
Beispiel #2
0
        public void CustomerService(AddClientsGroup request)
        {
            // Получаем из базы все столики которые больше или равно размеру группы
            var          freeTables   = _connection.Query <Table>("GetFreeTables", new { request.Size });
            ClientsGroup clientsGroup = new ClientsGroup();

            // Если нет подходящих столиков
            if (freeTables.Count == 0)
            {
                clientsGroup = new ClientsGroup
                {
                    TableId = null,
                    Size    = request.Size,
                    Status  = Status.InQueue
                };
                // Процедура для добавления группы клиентов в базу
                _connection.Execute("AddClientsGroup", clientsGroup);
            }
            else
            {
                Table freeTable = new Table();
                // Получаем свободный столик, если нет, то столик в котором сидят люди
                freeTable = freeTables.FirstOrDefault(f => f.IsFree)
                            ?? freeTables.FirstOrDefault(f => !f.IsFree);
                clientsGroup = new ClientsGroup
                {
                    TableId = freeTable.Id,
                    Size    = request.Size,
                    Status  = Status.OnTable
                };
                freeTable.FreeSize -= clientsGroup.Size;
                // Добавляем группу в базу данных и изменяем столик
                _connection.Execute("AddClientsGroupAndUpdateTable", new
                {
                    clientsGroup.Size, clientsGroup.Status, clientsGroup.TableId, freeTable.IsFree, freeTable.FreeSize
                });
                // Получаем группу клиентов которые стоят в очереди
                var clientsGroups = _connection.Query <ClientsGroup>("GetClientsGroupInQueue");
                // Если есть такие, то проверям их состояние
                if (clientsGroups.Count > 0)
                {
                    ClientsStatusInTheQueue(clientsGroups);
                }
            }
        }
Beispiel #3
0
        public void OnLeave(ClientsGroup group)
        {
            // Получаем столик за которым сидит группа
            var table = _connection.Query <Table>("GetClientsGroupTable", new { group.TableId })
                        .FirstOrDefault();

            if (table != null)
            {
                table.FreeSize += group.Size;
                // Удаляем группу из базы и изменяем столик
                _connection.Execute("RemoveClientsGroupAndUpdateTable", new
                {
                    group.Id, group.TableId, table.IsFree, table.FreeSize
                });

                // Получаем группу клиентов которые стоят в очереди
                var clientsGroupsInTheQueue = _connection.Query <ClientsGroup>("GetClientsGroupInQueue").ToList();
                // Получаем подходящую группу по размеру на столик
                var fromQueueClient = clientsGroupsInTheQueue.FirstOrDefault(c => c.Size <= table.FreeSize);
                if (fromQueueClient != null)
                {
                    // Получаем группы стоящие перед fromQueueClient
                    List <ClientsGroup> clientsGroupAheadOfQueue = clientsGroupsInTheQueue
                                                                   .Where(c => clientsGroupsInTheQueue.IndexOf(c) <
                                                                          clientsGroupsInTheQueue.IndexOf(fromQueueClient)).ToList();
                    // Изменяем размер столика
                    table.FreeSize -= fromQueueClient.Size;
                    // Если есть кто-то стоящие перед группой, проверяем их состояние
                    if (clientsGroupAheadOfQueue.Count != 0)
                    {
                        ClientsStatusInTheQueue(clientsGroupAheadOfQueue);
                    }
                    // Изменяем статус и TableId этой группы
                    fromQueueClient.TableId = table.Id;
                    fromQueueClient.Status  = Status.OnTable;
                    // Изменяем группу и столик из базы
                    _connection.Execute("UpdateClientsGroupAndUpdateTable", new
                    {
                        fromQueueClient.Id, fromQueueClient.Status, fromQueueClient.TableId, table.IsFree, table.FreeSize
                    });
                }
            }
        }
Beispiel #4
0
        public void PutTheTable(Table table, ClientsGroup group)
        {
            // устанавливаем id столика для клиента
            group.TableId = table.Id;

            // уменьшаем кол-во свободных мест за столиком
            table.FreeSize -= group.Size;

            // усаживаем за столик
            if (TableClients.ContainsKey(table.Id))
            {
                TableClients[table.Id].Add(group);
            }
            else
            {
                TableClients.Add(table.Id, new List <ClientsGroup> {
                    group
                });
            }
        }
Beispiel #5
0
        private static void Main(string[] args)
        {
            // создали 32 столика
            RestManager manager = new RestManager(CreateTables(32));

            // пришло 1000 клиентов
            foreach (ClientsGroup clientsGroup in CreateClientsGroups(1000))
            {
                manager.OnArrive(clientsGroup);
            }

            do
            {
                if (manager.TableClients.Count <= 0)
                {
                    continue;
                }

                for (int i = 0; i < manager.TableClients.Count; i++)
                {
                    KeyValuePair <Guid, List <ClientsGroup> > kvp = manager.TableClients.ElementAt(i);
                    if (kvp.Value.Count <= 0)
                    {
                        continue;
                    }

                    for (int j = 0; j < kvp.Value.Count; j++)
                    {
                        ClientsGroup group = kvp.Value[j];
                        // клиент уходит
                        manager.OnLeave(group);
                    }
                }
            }while (manager.TotalClients > 0);

            Console.WriteLine($"Total Clients: {manager.TotalClients}");
            Console.WriteLine("Press any key to exit...");
            Console.ReadKey();
        }
Beispiel #6
0
        // new client(s) show up
        public void OnArrive(ClientsGroup group)
        {
            // Получаем столики по размеру равным или больше чем количество людей
            List <Table> freeTables = _tables.Where(t => t.FreeSize >= group.Size).ToList();

            if (!freeTables.Any())
            {
                _clientQueue.Add(group);
                return;
            }
            // Сортируем по размеру пустых столиков. Это нужно для того чтобы получить столик который меньше размером. Например чтобы не посадить 2 людей на столик 6-х
            freeTables = freeTables.OrderBy(t => t.FreeSize).ToList();
            // Получаем столик который свободен или в который уже сидят люди но есть свободные места
            Table freeTable = freeTables.FirstOrDefault(t => t.IsFree)
                              ?? freeTables.FirstOrDefault(t => !t.IsFree);

            PutTheTable(freeTable, group);
            // Если есть клиенты в очереди, проверяем их состояние
            if (_clientQueue.Count > 0)
            {
                ClientStatusInTheQueue(new List <ClientsGroup>());
            }
        }
Beispiel #7
0
        // client(s) leave, either served or simply abandoning the queue
        public void OnLeave(ClientsGroup group)
        {
            // за каким столиком сидит клиент
            Table table = Lookup(group);

            if (table != null)
            {
                // удаляем клиента
                TableClients[group.TableId].RemoveAll(client => client.Id == group.Id);

                // увеличиваем кол-во свободных мест столика
                table.FreeSize += group.Size;

                // ищем подходящего клиента из очереди
                ClientsGroup fromQueueClient = _clientQueue.FirstOrDefault(client => table.FreeSize >= client.Size);

                if (fromQueueClient == null)
                {
                    return;
                }

                // получаем групп стоящих перед fromQueueClient
                List <ClientsGroup> clientsGroupAheadOfQueue = _clientQueue.Where(clientsGroup =>
                                                                                  _clientQueue.IndexOf(clientsGroup) < _clientQueue.IndexOf(fromQueueClient)).ToList();


                PutTheTable(table, fromQueueClient);

                if (clientsGroupAheadOfQueue.Count != 0)
                {
                    ClientStatusInTheQueue(clientsGroupAheadOfQueue);
                }

                // удаляем из очереди
                _clientQueue.RemoveAll(client => client.Id == fromQueueClient.Id);
            }
        }
Beispiel #8
0
 // return table where a given client group is seated,
 // or null if it is still queuing or has already left
 public Table Lookup(ClientsGroup group)
 {
     return(_tables.FirstOrDefault(table => table.Id == group.TableId));
 }
Beispiel #9
0
 /// <summary>
 /// Get table where a given client group is seated,
 /// or null if it is still queuing or has already left
 /// </summary>
 /// <param name="group">Finding group</param>
 /// <returns>Returns table</returns>
 public Table Lookup(ClientsGroup group)
 {
     return(this.tables.SingleOrDefault(t => t.GetGroup(group.Id) != null));
 }
Beispiel #10
0
 /// <summary>
 /// client(s) leave, either served or simply abandoning the queue
 /// </summary>
 /// <param name="group">Waiting clients group or one person</param>
 public void OnLeave(ClientsGroup group)
 {
     this.waitingClientsQueue.Remove(group);
     this.WorkClientsQueue();
 }
Beispiel #11
0
 /// <summary>
 /// new client(s) show up
 /// </summary>
 /// <param name="group">New clients group or one person</param>
 public void OnArrive(ClientsGroup group)
 {
     this.waitingClientsQueue.Add(group);
     this.WorkClientsQueue();
 }