Skip to content

Commit

Permalink
match/filter: cache the number of arg matches to check
Browse files Browse the repository at this point in the history
Signed-off-by: Tom Gundersen <[email protected]>
  • Loading branch information
teg committed Jan 29, 2018
1 parent dfcdee3 commit ccd06b2
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/bus/driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,8 @@ static int driver_monitor(Bus *bus, Peer *sender, Message *message) {
filter.interface = message->metadata.fields.interface;
filter.member = message->metadata.fields.member,
filter.path = message->metadata.fields.path;
filter.n_args = message->metadata.n_args;
filter.n_argpaths = message->metadata.n_args;

for (size_t i = 0; i < message->metadata.n_args; ++i) {
if (message->metadata.args[i].element == 's') {
Expand Down Expand Up @@ -552,6 +554,8 @@ static int driver_notify_name_owner_changed(Bus *bus, MatchRegistry *matches, co
.argpaths[1] = old_owner,
.args[2] = new_owner,
.argpaths[2] = new_owner,
.n_args = 3,
.n_argpaths = 3,
};
static const CDVarType type[] = {
C_DVAR_T_INIT(
Expand Down
21 changes: 19 additions & 2 deletions src/bus/match.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,12 @@ static int match_keys_assign(MatchKeys *keys, const char *key, size_t n_key, con

if (match_key_equal("", key, n_key)) {
keys->filter.args[i] = value;
if (i + 1 > keys->filter.n_args)
keys->filter.n_args = i + 1;
} else if (match_key_equal("path", key, n_key)) {
keys->filter.argpaths[i] = value;
if (i + 1 > keys->filter.n_argpaths)
keys->filter.n_argpaths = i + 1;
} else
return MATCH_E_INVALID;
} else {
Expand Down Expand Up @@ -306,7 +310,10 @@ static bool match_keys_match_filter(MatchKeys *keys, MatchFilter *filter) {
if (keys->arg0namespace && !match_string_prefix(filter->args[0], keys->arg0namespace, '.', false))
return false;

for (unsigned int i = 0; i < C_ARRAY_SIZE(filter->args); i ++) {
if (keys->filter.n_args > filter->n_args)
return false;

for (unsigned int i = 0; i < keys->filter.n_args || i < keys->filter.n_argpaths; i ++) {
if (keys->filter.args[i] && !c_string_equal(keys->filter.args[i], filter->args[i]))
return false;

Expand Down Expand Up @@ -348,7 +355,17 @@ static int match_rule_compare(CRBTree *tree, void *k, CRBNode *rb) {
if (key1->filter.type < key2->filter.type)
return -1;

for (size_t i = 0; i < C_ARRAY_SIZE(key1->filter.args); i ++) {
if (key1->filter.n_args < key2->filter.n_args)
return -1;
if (key1->filter.n_args > key2->filter.n_args)
return 1;

if (key1->filter.n_argpaths < key2->filter.n_argpaths)
return -1;
if (key1->filter.n_argpaths > key2->filter.n_argpaths)
return 1;

for (size_t i = 0; i < key1->filter.n_args || i < key1->filter.n_argpaths; i ++) {
if ((r = c_string_compare(key1->filter.args[i], key2->filter.args[i])) ||
(r = c_string_compare(key1->filter.argpaths[i], key2->filter.argpaths[i])))
return r;
Expand Down
2 changes: 2 additions & 0 deletions src/bus/match.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ struct MatchFilter {
const char *member;
const char *path;
const char *args[64];
size_t n_args;
const char *argpaths[64];
size_t n_argpaths;
};

#define MATCH_FILTER_INIT { \
Expand Down
2 changes: 2 additions & 0 deletions src/bus/peer.c
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,8 @@ int peer_broadcast(PolicySnapshot *sender_policy, NameSet *sender_names, MatchRe
filter->interface = message->metadata.fields.interface;
filter->member = message->metadata.fields.member,
filter->path = message->metadata.fields.path;
filter->n_args = message->metadata.n_args;
filter->n_argpaths = message->metadata.n_args;

for (size_t i = 0; i < message->metadata.n_args; ++i) {
if (message->metadata.args[i].element == 's') {
Expand Down
4 changes: 4 additions & 0 deletions src/bus/test-match.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ static void test_individual_matches(void) {
filter = (MatchFilter)MATCH_FILTER_INIT;
assert(!test_match("arg0=/com/example/foo/", &filter));
filter.args[0] = "/com/example/foo/";
filter.n_args = 1;
assert(test_match("arg0=/com/example/foo/", &filter));
assert(!test_match("arg0=/com/example/foo/bar", &filter));
assert(!test_match("arg0=/com/example/foobar", &filter));
Expand All @@ -219,6 +220,7 @@ static void test_individual_matches(void) {
filter = (MatchFilter)MATCH_FILTER_INIT;
assert(!test_match("arg0path=/com/example/foo/", &filter));
filter.argpaths[0] = "/com/example/foo/";
filter.n_argpaths = 1;
assert(test_match("arg0path=/com/example/foo/", &filter));
assert(test_match("arg0path=/com/example/foo/bar", &filter));
assert(!test_match("arg0path=/com/example/foobar", &filter));
Expand All @@ -229,6 +231,7 @@ static void test_individual_matches(void) {
filter = (MatchFilter)MATCH_FILTER_INIT;
assert(!test_match("arg0path=/com/example/foo", &filter));
filter.argpaths[0] = "/com/example/foo";
filter.n_argpaths = 1;
assert(test_match("arg0path=/com/example/foo", &filter));
assert(!test_match("arg0path=/com/example/foo/bar", &filter));
assert(!test_match("arg0path=/com/example/foobar", &filter));
Expand All @@ -239,6 +242,7 @@ static void test_individual_matches(void) {
filter = (MatchFilter)MATCH_FILTER_INIT;
assert(!test_match("arg0namespace=com.example.foo", &filter));
filter.args[0] = "com.example.foo";
filter.n_args = 1;
assert(test_match("arg0namespace=com.example.foo", &filter));
assert(!test_match("arg0namespace=com.example.foo.bar", &filter));
assert(!test_match("arg0namespace=com.example.foobar", &filter));
Expand Down

0 comments on commit ccd06b2

Please sign in to comment.