diff --git a/event_predicate.c b/event_predicate.c new file mode 100644 index 0000000..8ebfde6 --- /dev/null +++ b/event_predicate.c @@ -0,0 +1,190 @@ +#include +#include "event_predicate.h" + +typedef struct { + size_t capacity; + size_t length; + EventPredicate *values; +} EventPredicateList; + +static EventPredicateList predicates = { + .length = 0, + .capacity = 0, + .values = NULL, +}; + +static bool +event_predicate_list_extend(EventPredicateList * lst) +{ + size_t capacity = lst->capacity; + capacity = capacity + (capacity >> 1) + 1; + + EventPredicate *new_values; + if (lst->values) { + new_values = reallocarray(lst->values, capacity, sizeof(EventPredicate)); + } else { + new_values = T_ALLOC(capacity, EventPredicate); + } + if (!new_values) { + return false; + } + lst->values = new_values; + + lst->capacity = capacity; + return true; +} + +static void +event_predicate_list_clear(EventPredicateList * lst) +{ + if (lst->values) { + free(lst->values); + lst->values = NULL; + } + lst->capacity = 0; + lst->length = 0; +} + +EventPredicateHandle +event_predicate_register(EventPredicate filter) +{ + size_t i = predicates.length; + if (i >= INT32_MAX) { + return -1; + } + while (i <= predicates.capacity) { + event_predicate_list_extend(&predicates); + } + predicates.values[i] = filter; + predicates.length = i + 1; + return (EventPredicateHandle) i; +} + +static EventPredicate* +event_predicate_get_ptr(EventPredicateHandle handle) +{ + if (handle < 0 || (size_t) handle >= predicates.length) { + return NULL; + } + return &predicates.values[handle]; +} + +EventPredicate +event_predicate_get(EventPredicateHandle handle) +{ + EventPredicate *ptr = event_predicate_get_ptr(handle); + if (ptr) { + return *ptr; + } else { + return (EventPredicate) { + .type = EVPRED_INVALID, + .enabled = false, + .inverted = false, + }; + } +} + +EventPredicateResult +event_predicate_apply(EventPredicateHandle handle, EventNode * event) +{ + EventPredicate *ptr = event_predicate_get_ptr(handle); + if (!ptr) { + return EVPREDRES_DISABLED; + } + if (!ptr->enabled) { + return EVPREDRES_DISABLED; + } + bool accepted = false; + switch (ptr->type) { + case EVPRED_INVALID: + return EVPREDRES_DISABLED; + case EVPRED_ACCEPT: + accepted = true; + break; + case EVPRED_CODE_NS...EVPRED_PAYLOAD: + if (!event) { + return EVPREDRES_DISABLED; + } + { + int64_t actual; + switch (ptr->type) { + case EVPRED_CODE_NS: + actual = event->data.code.ns; + break; + case EVPRED_CODE_MAJOR: + actual = event->data.code.major; + break; + case EVPRED_CODE_MINOR: + actual = event->data.code.minor; + break; + case EVPRED_PAYLOAD: + actual = event->data.payload; + break; + default: + return EVPREDRES_DISABLED; + } + accepted = ptr->range_data.min_value <= actual && actual <= ptr->range_data.max_value; + } + break; + case EVPRED_CONJUNCTION: + case EVPRED_DISJUNCTION: + if (!ptr->aggregate_data.handles) { + return EVPREDRES_DISABLED; + } + { + bool disjunction = ptr->type == EVPRED_DISJUNCTION; + accepted = !disjunction; + for (size_t i = 0; i < ptr->aggregate_data.length; ++i) { + EventPredicateResult child_result = event_predicate_apply(ptr->aggregate_data.handles[i], event); // TODO protect from stack overflow + bool should_stop = false; + switch (child_result) { + case EVPREDRES_DISABLED: + continue; + case EVPREDRES_ACCEPTED: + should_stop = false; + break; + case EVPREDRES_REJECTED: + should_stop = true; + break; + } + if (disjunction) { + should_stop = !should_stop; + } + if (should_stop) { + accepted = disjunction; + break; + } + } + } + break; + } + if (ptr->inverted) { + accepted = !accepted; + } + return accepted ? EVPREDRES_ACCEPTED : EVPREDRES_REJECTED; +} + +void +event_predicate_set_enabled(EventPredicateHandle handle, bool enabled) +{ + EventPredicate *ptr = event_predicate_get_ptr(handle); + if (!ptr) { + return; + } + ptr->enabled = enabled; +} + +void event_predicate_set_inverted(EventPredicateHandle handle, bool inverted) +{ + EventPredicate *ptr = event_predicate_get_ptr(handle); + if (!ptr) { + return; + } + ptr->inverted = inverted; +} + +void +event_predicate_reset() +{ + event_predicate_list_clear(&predicates); +} diff --git a/event_predicate.h b/event_predicate.h new file mode 100644 index 0000000..2b1a240 --- /dev/null +++ b/event_predicate.h @@ -0,0 +1,51 @@ +#ifndef PREDS_H_ +#define PREDS_H_ + +#include "events.h" + +typedef struct event_predicate EventPredicate; +typedef int32_t EventPredicateHandle; + +typedef enum { + EVPRED_INVALID, + EVPRED_ACCEPT, + // Range + EVPRED_CODE_NS, + EVPRED_CODE_MAJOR, + EVPRED_CODE_MINOR, + EVPRED_PAYLOAD, + // Aggregation + EVPRED_CONJUNCTION, + EVPRED_DISJUNCTION, +} EventPredicateType; + +typedef enum { + EVPREDRES_DISABLED = -1, + EVPREDRES_REJECTED = 0, + EVPREDRES_ACCEPTED = 1, +} EventPredicateResult; + +struct event_predicate { + EventPredicateType type; + bool enabled; + bool inverted; + union { + struct { + int64_t min_value; + int64_t max_value; + } range_data; + struct { + size_t length; + EventPredicateHandle *handles; + } aggregate_data; + }; +}; + +EventPredicateHandle event_predicate_register(EventPredicate filter); +EventPredicate event_predicate_get(EventPredicateHandle handle); +EventPredicateResult event_predicate_apply(EventPredicateHandle handle, EventNode * event); +void event_predicate_set_enabled(EventPredicateHandle handle, bool enabled); +void event_predicate_set_inverted(EventPredicateHandle handle, bool inverted); +void event_predicate_reset(); + +#endif /* end of include guard: PREDS_H_ */ diff --git a/filters.c b/filters.c deleted file mode 100644 index 067e9c7..0000000 --- a/filters.c +++ /dev/null @@ -1,190 +0,0 @@ -#include -#include "filters.h" - -typedef struct { - size_t capacity; - size_t length; - EventFilter *values; -} EventFilterList; - -static EventFilterList filters = { - .length = 0, - .capacity = 0, - .values = NULL, -}; - -static bool -event_filter_list_extend(EventFilterList * lst) -{ - size_t capacity = lst->capacity; - capacity = capacity + (capacity >> 1) + 1; - - EventFilter *new_values; - if (lst->values) { - new_values = reallocarray(lst->values, capacity, sizeof(EventFilter)); - } else { - new_values = T_ALLOC(capacity, EventFilter); - } - if (!new_values) { - return false; - } - lst->values = new_values; - - lst->capacity = capacity; - return true; -} - -static void -event_filter_list_clear(EventFilterList * lst) -{ - if (lst->values) { - free(lst->values); - lst->values = NULL; - } - lst->capacity = 0; - lst->length = 0; -} - -EventFilterHandle -event_filter_register(EventFilter filter) -{ - size_t i = filters.length; - if (i >= INT32_MAX) { - return -1; - } - while (i <= filters.capacity) { - event_filter_list_extend(&filters); - } - filters.values[i] = filter; - filters.length = i + 1; - return (EventFilterHandle) i; -} - -static EventFilter* -event_filter_get_ptr(EventFilterHandle handle) -{ - if (handle < 0 || (size_t) handle >= filters.length) { - return NULL; - } - return &filters.values[handle]; -} - -EventFilter -event_filter_get(EventFilterHandle handle) -{ - EventFilter *ptr = event_filter_get_ptr(handle); - if (ptr) { - return *ptr; - } else { - return (EventFilter) { - .type = EVFILTER_INVALID, - .enabled = false, - .inverted = false, - }; - } -} - -EventFilterResult -event_filter_apply(EventFilterHandle handle, EventNode * event) -{ - EventFilter *ptr = event_filter_get_ptr(handle); - if (!ptr) { - return EVFILTERRES_DISABLED; - } - if (!ptr->enabled) { - return EVFILTERRES_DISABLED; - } - bool accepted = false; - switch (ptr->type) { - case EVFILTER_INVALID: - return EVFILTERRES_DISABLED; - case EVFILTER_ACCEPT: - accepted = true; - break; - case EVFILTER_CODE_NS...EVFILTER_PAYLOAD: - if (!event) { - return EVFILTERRES_DISABLED; - } - { - int64_t actual; - switch (ptr->type) { - case EVFILTER_CODE_NS: - actual = event->data.code.ns; - break; - case EVFILTER_CODE_MAJOR: - actual = event->data.code.major; - break; - case EVFILTER_CODE_MINOR: - actual = event->data.code.minor; - break; - case EVFILTER_PAYLOAD: - actual = event->data.payload; - break; - default: - return EVFILTERRES_DISABLED; - } - accepted = ptr->range_data.min_value <= actual && actual <= ptr->range_data.max_value; - } - break; - case EVFILTER_CONJUNCTION: - case EVFILTER_DISJUNCTION: - if (!ptr->aggregate_data.handles) { - return EVFILTERRES_DISABLED; - } - { - bool disjunction = ptr->type == EVFILTER_DISJUNCTION; - accepted = !disjunction; - for (size_t i = 0; i < ptr->aggregate_data.length; ++i) { - EventFilterResult child_result = event_filter_apply(ptr->aggregate_data.handles[i], event); // TODO protect from stack overflow - bool should_stop = false; - switch (child_result) { - case EVFILTERRES_DISABLED: - continue; - case EVFILTERRES_ACCEPTED: - should_stop = false; - break; - case EVFILTERRES_REJECTED: - should_stop = true; - break; - } - if (disjunction) { - should_stop = !should_stop; - } - if (should_stop) { - accepted = disjunction; - break; - } - } - } - break; - } - if (ptr->inverted) { - accepted = !accepted; - } - return accepted ? EVFILTERRES_ACCEPTED : EVFILTERRES_REJECTED; -} - -void -event_filter_set_enabled(EventFilterHandle handle, bool enabled) -{ - EventFilter *ptr = event_filter_get_ptr(handle); - if (!ptr) { - return; - } - ptr->enabled = enabled; -} - -void event_filter_set_inverted(EventFilterHandle handle, bool inverted) -{ - EventFilter *ptr = event_filter_get_ptr(handle); - if (!ptr) { - return; - } - ptr->inverted = inverted; -} - -void -event_filter_reset() -{ - event_filter_list_clear(&filters); -} diff --git a/filters.h b/filters.h deleted file mode 100644 index 6037fbf..0000000 --- a/filters.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef FILTERS_H_ -#define FILTERS_H_ - -#include "events.h" - -typedef struct event_filter EventFilter; -typedef int32_t EventFilterHandle; - -typedef enum { - EVFILTER_INVALID, - EVFILTER_ACCEPT, - // Range - EVFILTER_CODE_NS, - EVFILTER_CODE_MAJOR, - EVFILTER_CODE_MINOR, - EVFILTER_PAYLOAD, - // Aggregation - EVFILTER_CONJUNCTION, - EVFILTER_DISJUNCTION, -} EventFilterType; - -typedef enum { - EVFILTERRES_DISABLED = -1, - EVFILTERRES_REJECTED = 0, - EVFILTERRES_ACCEPTED = 1, -} EventFilterResult; - -struct event_filter { - EventFilterType type; - bool enabled; - bool inverted; - union { - struct { - int64_t min_value; - int64_t max_value; - } range_data; - struct { - size_t length; - EventFilterHandle *handles; - } aggregate_data; - }; -}; - -EventFilterHandle event_filter_register(EventFilter filter); -EventFilter event_filter_get(EventFilterHandle handle); -EventFilterResult event_filter_apply(EventFilterHandle handle, EventNode * event); -void event_filter_set_enabled(EventFilterHandle handle, bool enabled); -void event_filter_set_inverted(EventFilterHandle handle, bool inverted); -void event_filter_reset(); - -#endif /* end of include guard: FILTERS_H_ */