Проблема множественных ассоциаций с C++
Вопрос
Как бы вы решили эту проблему?(Поначалу это казалось простым, потом показалось мне загадочным).
- У вас есть класс под названием «Исполнитель».Предположим, у вас есть много его экземпляров, и они делают разные вещи при вызове метода do(Argument).
- Аргумент имеет два разных параметра: A* pa, B* pb (один из которых может быть нулевым).
- Теперь мне нужен менеджер классов, который получает значения аргументов и пересылает их соответствующему экземпляру Executor (назовем этот метод Filter).Это делается после того, как некоторое время назад каждый Исполнитель вызвал метод Manager.subscribe(A* pa, B* pb), чтобы сообщить, кто из них заинтересован.Обратите внимание, что:если pa или (не оба) pb равны NULL, это означает ЛЮБОЙ (я имею в виду, что если pa равно NULL, проверяется только pb).Конечно, не должно быть более одного Исполнителя.
- Реализация должна быть БЫСТРОЙ, в идеале должен быть вектор или что-то похожее на хеш-карту...НО СРАВНЕНИЕ ДОЛЖНО ПРОВОДИТЬСЯ ПО СОДЕРЖАНИЮ pa и pb, а не по их значению как указателей.
- Наконец, должна быть возможность отмены подписки исполнителем (не дожидаясь слишком долго).В любом случае я хочу, чтобы фильтрация, подписка и отмена подписки выполнялись очень быстро.
Я думал о многих схемах с хеш-картами, списками и мультикартами...Но всем им не хватает скорости, или легкости, или чего-то еще.Что бы вы сделали?
Решение
Я думаю, вы хотите создать класс под названием «Подписка», который представляет собой одну подписку от Исполнителя к Менеджеру, содержащую информацию о том, при каких условиях эта подписка будет активироваться, а также какой-то GUID или имя для этой подписки.Я думаю что-то вроде
class Subscription
{
GUID g;
A_filter a;
B_filter b;
Executor *e;
}
Подписка также будет иметь метод «Проверить», должна ли она запускаться на основе заданных значений для A и B, а затем вызвать исполнителя по этим параметрам, если они совпадают.
Тогда класс Manager будет содержать три карты, одну из этих Maps Guid to Subscription*, и позволит очень быстро отказаться от подписки. По сути, найдите GUID в запросе на отмену подписки, чтобы получить объект подписки, используйте этот объект, чтобы определить, какие значения для A и B возможно, потребуется удалить его с карты A и карты B, а затем удалить объект.Подписка — это всего лишь вопрос создания объекта подписки и добавления значений в карту Guid, карту A и карту B.
Выполняя поиск на основе (A, B), если A или B имеет значение null, вы выполняете поиск в другой хэш-таблице и запускаете возвращаемую подписку.Если ни A, ни B не равны нулю, все становится сложнее.
Здесь нужно найти пересечение возвращаемых наборов, просматривая A и B. Это можно сделать вручную, но более быстрый метод может заключаться в том, чтобы просто иметь одну дополнительную карту, к которой добавлен ключ B. А.