Rename event filters to predicates
This commit is contained in:
parent
9f876162e5
commit
2208131d68
|
@ -0,0 +1,190 @@
|
|||
#include <limits.h>
|
||||
#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);
|
||||
}
|
|
@ -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_ */
|
190
filters.c
190
filters.c
|
@ -1,190 +0,0 @@
|
|||
#include <limits.h>
|
||||
#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);
|
||||
}
|
51
filters.h
51
filters.h
|
@ -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_ */
|
Loading…
Reference in New Issue