Если у вас есть только небольшое количество возможных значений кортежей, имеет смысл написать какую-то хеш-функцию, которая может превратить их в целочисленные индексы для быстрого поиска.
Если есть <32 значений, вы можете сделать что-то с битовыми масками: </p>
unsigned int hash(char *value){...}
typedef struct _tuple {
unsigned int bitvalues;
void * data
} tuple;
tuple a,b,c,d;
a.bitvalues = hash("one");
a.bitvalues |= hash("four");
//a.data = something;
unsigned int event = 0;
//foreach value in event;
event |= hash(string_val);
// foreach tuple
if(x->bitvalues & test == test)
{
//matches
}
Если существует слишком много значений для решения битовой маски, у вас может быть массив связанных списков. Пройдите каждый пункт в событии. Если элемент соответствует key_one, пройдитесь по кортежам с первым ключом и проверьте событие для второго ключа:
typedef struct _tuple {
unsigned int key_one;
unsigned int key_two;
_tuple *next;
void * data;
} tuple;
tuple a,b,c,d;
a.key_one = hash("one");
a.key_two = hash("four");
tuple * list = malloc(/*big enough for all hash indexes*/
memset(/*clear list*/);
//foreach touple item
if(list[item->key_one])
put item on the end of the list;
else
list[item->key_one] = item;
//foreach event
//foreach key
if(item_ptr = list[key])
while(item_ptr.next)
if(!item_ptr.key_two || /*item has key_two*/)
//match
item_ptr = item_ptr.next;
Этот код никоим образом не проверен и, вероятно, содержит много мелких ошибок, но вы должны понять. (одна ошибка, которая была исправлена, была условием проверки соответствия кортежей)
Если скорость обработки событий имеет первостепенное значение, имеет смысл перебирать все ваши построенные кортежи, подсчитывать количество вхождений и проходить, возможно, переупорядочение ключа один / ключ два из каждого кортежа, чтобы получить наиболее уникальное значение указан первым