-
Notifications
You must be signed in to change notification settings - Fork 351
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor internal implementation of rules #607
Comments
The approach seems tempting. Running two times over the list might be a downside, but I'd gladly accept it if it allows abstraction of our rule. Especially this lump of code would vanish Lines 93 to 104 in 7b3d85a
and would get replaced with a simple for loop: bool rule_matches_notification(struct rule *r, struct notification *n)
{
for (struct rulepart **r->match_rules; *rp; rp++)
if (!rule_part_matches(n, *rp)
return false;
return true;
} Sexy. But, how do you solve That has to be a super huge switch case fuckup: bool rule_part_matches(struct rule_part rp, notification *n)
{
switch (rp->match) {
case MATCH_APPNAME:
return fnmatch(n->appname, rp->data...);
break;
case MATCH_...:
return fnmatch(n->..., rp->data...);
break;
default:
LOG_C("Invalid enum");
}
} Complexity just moved to another function. But it might be better to have a switch case instead of a hard wired list. But wait, really? Keep in mind, that this is an invalid rule: [rulename]
msg_urgency = low
msg_urgency = wrong
timeout = 10 It's forbidden and useless to have two values to apply to the same field. One value has to win this field. A switch/case statement would help, processing multiple fields. But we won't ever have this. |
Another note on the data space: Also keep in mind, that an This makes the new rule struct at least 16 bytes long with another 16 bytes per match/set declaration. For myself, I've got on average 3 lines per rule in my config. Without the actual data, the structs take In comparison to 168 Bytes of a current rule struct, that's 104 bytes on average shave off. I should reiterate the advantages of the current approach:
|
Currently we're storing the rules in a huge struct. This is obviously neither space nor time efficient as we store a full value for all unset rules and on match we have to compare all possible match and set rules.
My proposed implementation would be something like this: (pseudocode, don't expect it to compile! :) )
So as it's apparent this involves having each rule item in an enum, and inside the rule struct we have 2 arrays one for the match rules and one for the set rule.
In order to apply the rule we simply iterate over the match array and check if each rule_part matches correctly. If it does we start iterating on the set rules and applying each one appropriately.
The 2 big downsides are:
We have to go through each rule twice, one to count the number of match and set rules in order to create the array and one got actually creating it.
This may be remedied by replacing the array with a linked list but that may be overcomplicating it.
Given Cs quite stingy approach with types we (unfortunately) have to abuse the void pointer again which leads to a big number of tiny allocations which might not be the best thing
An alternative here might be to replace the void pointer with a union of every possible data type.
The text was updated successfully, but these errors were encountered: