Sobes.tech
Middle+

Оқиғалар менеджерин ишке ашырыңыз, ал ар түрдүү тартипте келген окуяларды кабыл алып, алардын туура тартибинде, ID боюнча (1-ден баштап, ар бири +1) жөнөтсүн. Окуялар бир нече каналдардан келип, тартип ар бир канал үчүн өзүнчө сакталуусу керек. Кайталаган окуяларды эске албоо керек. Жөнөтүү үчүн sendEvent функциясын колдонуңуз.

sobes.tech AI

AIден жооп

Для решения задачи менеджера событий с поддержкой нескольких каналов и упорядочиванием событий по ID внутри каждого канала, можно использовать структуру данных, которая хранит для каждого канала:

  • ожидаемый следующий ID события (начинается с 1)
  • буфер для хранения пришедших событий с ID больше ожидаемого
  • множество для отслеживания уже обработанных ID (чтобы игнорировать дубликаты)

При поступлении нового события:

  1. Проверяем, не был ли он уже обработан (по множеству).
  2. Если ID равен ожидаемому, отправляем событие и увеличиваем ожидаемый ID, затем проверяем буфер, есть ли следующие события подряд, и отправляем их по порядку.
  3. Если ID больше ожидаемого, кладём событие в буфер.
  4. Если ID меньше ожидаемого — игнорируем (дубликат или уже обработано).

Пример на JavaScript:

class EventManager {
  constructor(sendEvent) {
    this.sendEvent = sendEvent;
    this.channels = new Map();
  }

  _getChannelState(channel) {
    if (!this.channels.has(channel)) {
      this.channels.set(channel, {
        nextId: 1,
        buffer: new Map(),
        processed: new Set()
      });
    }
    return this.channels.get(channel);
  }

  receiveEvent(channel, event) {
    const state = this._getChannelState(channel);
    const id = event.id;

    if (state.processed.has(id)) {
      // Дубликат
      return;
    }

    if (id === state.nextId) {
      this.sendEvent(channel, event);
      state.processed.add(id);
      state.nextId++;

      // Проверяем буфер на последовательные события
      while (state.buffer.has(state.nextId)) {
        const nextEvent = state.buffer.get(state.nextId);
        state.buffer.delete(state.nextId);
        this.sendEvent(channel, nextEvent);
        state.processed.add(state.nextId);
        state.nextId++;
      }
    } else if (id > state.nextId) {
      // Сохраняем в буфер
      if (!state.buffer.has(id)) {
        state.buffer.set(id, event);
      }
    }
    // Если id < nextId — игнорируем
  }
}

// Пример использования:
// const manager = new EventManager((channel, event) => console.log(`Send event ${event.id} from ${channel}`));
// manager.receiveEvent('channel1', {id: 2});
// manager.receiveEvent('channel1', {id: 1});
// manager.receiveEvent('channel1', {id: 2}); // дубликат, игнорируется