summaryrefslogtreecommitdiff
path: root/lib/match.c
diff options
context:
space:
mode:
authorJarno Rajahalme <jrajahalme@nicira.com>2015-07-15 13:17:01 -0700
committerJarno Rajahalme <jrajahalme@nicira.com>2015-07-15 13:17:10 -0700
commitceb3bd6731b90c1ec466777f23efab6991800e37 (patch)
tree9d7dab2bd49a46962b480300316314d89ac37f2c /lib/match.c
parent8fd4792403254f868398a89fb5625830ee5a08eb (diff)
downloadopenvswitch-ceb3bd6731b90c1ec466777f23efab6991800e37.tar.gz
match: Single malloc minimatch.
Allocate the miniflow and minimask in struct minimatch at once, so that they are consecutive in memory. This halves the number of allocations, and allows smaller minimatches to share the same cache line. After this a minimatch has one heap allocation for all it's data. Previously it had either none (when data was small enough to fit in struct miniflow's inline buffer), or two (when the inline buffer was insufficient). Hopefully always having one performs almost the same as none or two, in average. Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com> Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/match.c')
-rw-r--r--lib/match.c17
1 files changed, 12 insertions, 5 deletions
diff --git a/lib/match.c b/lib/match.c
index 2119ed705..6d4f1a360 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -1195,8 +1195,13 @@ match_print(const struct match *match)
void
minimatch_init(struct minimatch *dst, const struct match *src)
{
- dst->mask = minimask_create(&src->wc);
- dst->flow = miniflow_create_with_minimask(&src->flow, dst->mask);
+ struct miniflow tmp;
+
+ miniflow_map_init(&tmp, &src->wc.masks);
+ /* Allocate two consecutive miniflows. */
+ miniflow_alloc(dst->flows, 2, &tmp);
+ miniflow_init(dst->flow, &src->flow);
+ minimask_init(dst->mask, &src->wc);
}
/* Initializes 'dst' as a copy of 'src'. The caller must eventually free 'dst'
@@ -1204,8 +1209,11 @@ minimatch_init(struct minimatch *dst, const struct match *src)
void
minimatch_clone(struct minimatch *dst, const struct minimatch *src)
{
- dst->flow = miniflow_clone(src->flow);
- dst->mask = minimask_clone(src->mask);
+ /* Allocate two consecutive miniflows. */
+ size_t data_size = miniflow_alloc(dst->flows, 2, &src->mask->masks);
+
+ memcpy(dst->flow->values, src->flow->values, data_size);
+ memcpy(dst->mask->masks.values, src->mask->masks.values, data_size);
}
/* Initializes 'dst' with the data in 'src', destroying 'src'. The caller must
@@ -1223,7 +1231,6 @@ void
minimatch_destroy(struct minimatch *match)
{
free(match->flow);
- free(match->mask);
}
/* Initializes 'dst' as a copy of 'src'. */