diff options
author | Jarno Rajahalme <jrajahalme@nicira.com> | 2013-12-20 08:16:31 -0800 |
---|---|---|
committer | Jarno Rajahalme <jrajahalme@nicira.com> | 2013-12-20 08:16:31 -0800 |
commit | 83916319a914a4111cabf52a115368ebf5320123 (patch) | |
tree | b2ad5e2faa77eef82197146147f31806da2f476c /lib/flow.c | |
parent | 15155807de9fd3e50f095494a694257e088555fe (diff) | |
download | openvswitch-83916319a914a4111cabf52a115368ebf5320123.tar.gz |
lib/flow: Skip minimask value checks.
We allow zero 'values' in a miniflow for it to have the same map
as the corresponding minimask. Minimasks themselves never have
zero data values, though. Document this and optimize the code
accordingly.
v2:
- Made miniflow_get_map_in_range() to return data offset instead of
a pointer via the last parameter.
- Simplified minimatch_hash_in_range() by removing pointer arithmetic.
Signed-off-by: Jarno Rajahalme <jrajahalme@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/flow.c')
-rw-r--r-- | lib/flow.c | 38 |
1 files changed, 15 insertions, 23 deletions
diff --git a/lib/flow.c b/lib/flow.c index 13d0aa559..f1d2cad29 100644 --- a/lib/flow.c +++ b/lib/flow.c @@ -725,24 +725,22 @@ flow_wildcards_fold_minimask(struct flow_wildcards *wc, flow_union_with_miniflow(&wc->masks, &mask->masks); } -inline uint64_t +uint64_t miniflow_get_map_in_range(const struct miniflow *miniflow, - uint8_t start, uint8_t end, const uint32_t **data) + uint8_t start, uint8_t end, unsigned int *offset) { uint64_t map = miniflow->map; - uint32_t *p = miniflow->values; + *offset = 0; if (start > 0) { uint64_t msk = (UINT64_C(1) << start) - 1; /* 'start' LSBs set */ - p += count_1bits(map & msk); /* Skip to start. */ + *offset = count_1bits(map & msk); map &= ~msk; } if (end < FLOW_U32S) { uint64_t msk = (UINT64_C(1) << end) - 1; /* 'end' LSBs set */ map &= msk; } - - *data = p; return map; } @@ -754,8 +752,10 @@ flow_wildcards_fold_minimask_range(struct flow_wildcards *wc, uint8_t start, uint8_t end) { uint32_t *dst_u32 = (uint32_t *)&wc->masks; - const uint32_t *p; - uint64_t map = miniflow_get_map_in_range(&mask->masks, start, end, &p); + unsigned int offset; + uint64_t map = miniflow_get_map_in_range(&mask->masks, start, end, + &offset); + const uint32_t *p = mask->masks.values + offset; for (; map; map = zero_rightmost_1bit(map)) { dst_u32[raw_ctz(map)] |= *p++; @@ -1516,11 +1516,7 @@ miniflow_hash_in_minimask(const struct miniflow *flow, hash = basis; for (map = mask->masks.map; map; map = zero_rightmost_1bit(map)) { - if (*p) { - int ofs = raw_ctz(map); - hash = mhash_add(hash, miniflow_get(flow, ofs) & *p); - } - p++; + hash = mhash_add(hash, miniflow_get(flow, raw_ctz(map)) & *p++); } return mhash_finish(hash, (p - mask->masks.values) * 4); @@ -1542,10 +1538,7 @@ flow_hash_in_minimask(const struct flow *flow, const struct minimask *mask, hash = basis; for (map = mask->masks.map; map; map = zero_rightmost_1bit(map)) { - if (*p) { - hash = mhash_add(hash, flow_u32[raw_ctz(map)] & *p); - } - p++; + hash = mhash_add(hash, flow_u32[raw_ctz(map)] & *p++); } return mhash_finish(hash, (p - mask->masks.values) * 4); @@ -1562,15 +1555,14 @@ flow_hash_in_minimask_range(const struct flow *flow, uint8_t start, uint8_t end, uint32_t *basis) { const uint32_t *flow_u32 = (const uint32_t *)flow; - const uint32_t *p; - uint64_t map = miniflow_get_map_in_range(&mask->masks, start, end, &p); + unsigned int offset; + uint64_t map = miniflow_get_map_in_range(&mask->masks, start, end, + &offset); + const uint32_t *p = mask->masks.values + offset; uint32_t hash = *basis; for (; map; map = zero_rightmost_1bit(map)) { - if (*p) { - hash = mhash_add(hash, flow_u32[raw_ctz(map)] & *p); - } - p++; + hash = mhash_add(hash, flow_u32[raw_ctz(map)] & *p++); } *basis = hash; /* Allow continuation from the unfinished value. */ |